1

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

例如。我正在使用开关和按钮。我不想再次生成重复使用的相同 arc4random 数。如果我有 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;
        }
4

2 回答 2

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 的情况下,偏差可以忽略不计。

于 2012-01-07T21:25:54.580 回答
-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。

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

于 2012-01-07T21:50:22.630 回答