4

我一直试图让非重复的 arc4random_uniform 为我的 iPhone 应用程序工作很长时间。在没有运气的情况下,在stackoverflow上完成了所有与此相关的问题和答案,现在我希望有人能帮助我。我想做的是在 1 到 104 之间选择 13 个不同的随机数。我已经让它工作到选择 13 个不同的数字,但有时其中两个是相同的。

int rand = arc4random_uniform(104);

这就是我正在做的事情,然后我使用 rand 从数组中进行选择。如果更容易打乱数组然后从顶部选择 13,那么我会尝试,但我需要帮助,因为这似乎更难。

感谢您的任何建议。

4

4 回答 4

14

没有任何保证ar4random_uniform()不会重复。想一想——你要求它产生一个介于 0 和 103 之间的数字。如果你这样做 105 次,它别无选择,只能重复它之前的选择之一。该函数如何知道您要请求多少次号码?

您要么必须检查已经获得的数字列表,如果重复,则请求新的数字列表,或者随机排列数组。为此,应该有很多关于 SO 的问题。这是最古老的方法之一:随机播放 NSMutableArray 的最佳方法是什么?.

还有不少关于非重复随机数的问题:https ://stackoverflow.com/search?q=%5Bobjc%5D+non-repeating+random+numbers

于 2012-04-19T17:40:18.820 回答
2

您可以像这样创建NSMutableSet并实现它:

NSMutableArray* numbers = [[NSMutableArray alloc] initWithCapacity: 13];
NSMutableSet* usedValues = [[NSMutableSet alloc] initWithCapacity: 13];

for (int i = 0; i < 13; i++) {
  int randomNum = arc4random_uniform(104);
  while ([usedValues containsObject: [NSNumber numberWithInt: randomNum]) {     
    randomNum = arc4random_uniform(104)
  }
  [[usedValues addObject: [NSNumber numberWithInt: randomNum];
  [numbers addObject: [[NSNumber numberWithInt: randomNum];
}
于 2014-07-22T21:21:57.477 回答
1

或者,您也可以创建一个由 105 个整数组成的可变数组,每个整数都是唯一的,并且 arc4random_uniform([arrayname count]) 然后从数组中删除相同的整数,然后您每次都会得到一个随机 int 而无需重复(尽管较小数组变得更容易预测下一个数字是什么,只是简单的概率)

于 2013-05-28T23:59:38.487 回答
0

这里描述了我为这个确切问题找到的最佳算法:

选择单个随机值组合的算法?

您只需循环 13 次,而不是打乱 104 个元素的数组。这是我在Objective C中的算法实现:

// Implementation of the Floyd algorithm from Programming Pearls.
// Returns a NSSet of num_values from 0 to max_value - 1.
static NSSet* getUniqueRandomNumbers(int num_values, int max_value) {
    assert(max_value >= num_values);
    NSMutableSet* set = [NSMutableSet setWithCapacity:num_values];
    for (int i = max_value - num_values; i < max_value; ++i) {
        NSNumber* rand = [NSNumber numberWithInt:arc4random_uniform(i)];
        if ([set containsObject:rand]) {
            [set addObject:[NSNumber numberWithInt:i]];
        } else {
            [set addObject:rand];
        }
    }
    return set;
}
于 2013-06-05T09:08:29.903 回答