非重复arc4random_uniform

时间:2012-04-19 17:30:49

标签: objective-c xcode arc4random

我一直试图让非重复的arc4random_uniform现在为我的iPhone应用程序工作多年。关于stackoverflow的所有问题和答案都没有运气,现在我希望有人可以帮助我。我想要做的是在1到104之间选择13个不同的随机数。我已经让它工作到选择13个不同的数字,但有时两个是相同的。

int rand = arc4random_uniform(104);

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

感谢任何建议。

4 个答案:

答案 0 :(得分:14)

不保证ar4random_uniform()不会重复。想想它一秒钟 - 你要求它产生0到103之间的数字。如果你这样做了一百零五次,它别无选择,只能重复其之前的一个选择。该函数如何知道您要请求一个号码的次数?

您必须查看已经获得的号码列表,如果重复或者随机播放,请申请新号码。关于此,应该有任何数量的问题。这是最古老的一个:What's the Best Way to Shuffle an NSMutableArray?

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

答案 1 :(得分: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];
}

答案 2 :(得分:1)

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

答案 3 :(得分:0)

我在这里描述了这个问题的最佳算法:

Algorithm to select a single, random combination of values?

不需要改组104个元素的数组,而只需循环13次。这是我在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;
}