在arc4random()号上使用一次

时间:2012-01-07 21:19:29

标签: iphone random sdk arc4random

如何编写不重复数字两次的arc4random()?

例如。我正在使用开关和按钮。我不想再次生成重用相同的arc4随机数。如果我有arc4random那一代数2,4,42,32,42 ...... 我不想再出现42。

我该如何避免这种情况?

  switch (arc4random() % 50 )
        {
            case 1:
                text.text = @"You are silly boy";
                break;
            case 2:
                text.text = @"Well, you very very silly"];
                break;
            case 3:
                text.text = @"stop being silly"];
                break;
            case 4:
                [text.text = @"silly... silly"];
                break;
            case 5:
                text.text = @"what you silly boy"];
                break;

           ...
            case 0:
                text.text = @"you silly"];
                break;
        }

2 个答案:

答案 0 :(得分:6)

arc4random()不是重复生成器,即每次调用都独立于所有其他调用。但这也意味着只调用arc4random()不会(通常)产生50个唯一数字。

一种方法是创建一个你想要的整数数组,然后遍历数组并将每一个与随机选择的另一个(在你的例子中)与(arc4random()%50)交换。他们只使用数组中的连续值,并在最后创建一个新数组并随机化它。

示例:列表中的值将是0到49之间的随机数,没有重复:

int n = 50;
int list[n];
for (int i = 0; i<n; i++)
    list[i] = i;

for (int i = n-1; i>=1; i--) {
    int ran = arc4random() % (i+1);
    int tmp = list[i];
    list[i] = list[ran];
    list[ran] = tmp;
}

for (int i = 0; i<n; i++)
    NSLog(@"%d", list[i]);

这是Fisher-Yates shuffle的现代版本,专为计算机使用而设计,由Richard Durstenfeld推出。

注意:使用mod创建一个子集会产生偏差,但在50的情况下偏差可以忽略不计。

答案 1 :(得分:-1)

这样做的一种方法如下:

static int maxNumOfCases = 50; //This could be any number of cases that you need in your app.

......

switch (arc4random() % (maxNumOfCases--)) {
            case 1:
                text.text = @"You are silly boy";
                break;
            case 2:
                text.text = @"Well, you very very silly"];
                break;
            case 3:
                text.text = @"stop being silly"];
                break;
            case 4:
                [text.text = @"silly... silly"];
                break;
            case 5:
                text.text = @"what you silly boy"];
                break;
                ...
            case 0:
            text.text = @"you silly"];
            break;
}

此代码始终在每次调用时切换到唯一的大小写。代码的工作方式是将每次调用时arc4random()的范围减小1。

更新:请注意,此方法会在运行结束时向较小范围的数字偏移更多。所以这不是真正的非重复随机数生成。但如果这不是一个问题,它可以很容易地包含在你的代码中。