【问题标题】:Non-repeating arc4random_uniform非重复 arc4random_uniform
【发布时间】:2012-04-19 17:30:49
【问题描述】:

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

int rand = arc4random_uniform(104);

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

感谢您的任何建议。

【问题讨论】:

  • 如果你想打乱一个数组或者从一个数组中选择随机项,我建议你搜索'objective-c array shuffle'或者'randomized queue'。

标签: objective-c xcode arc4random


【解决方案1】:

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

您要么必须检查已经获得的数字列表,如果重复,则请求新的数字列表,或者随机排列数组。为此,应该有很多关于 SO 的问题。这是最古老的之一:What's the Best Way to Shuffle an NSMutableArray?

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

【讨论】:

  • 好的,这基本上就是我想要的。很抱歉再次问同样的问题,我似乎无法让它与我看过的其他答案一起工作。
  • +1 更强烈地重申:如果arc4random_uniform() 不重复,它就不是随机的。对于相当小的范围,您不仅应该期望重复,还应该期望重复序列。对于非常小的范围(如掷硬币),您应该期待相当长的重复序列。如果您没有看到它们,那么您的随机数生成器可能有问题。不过,正如 Josh 所说,您真正想要的是随机播放。
  • 将它们放在一个集合中,直到 [set count] == 13。
【解决方案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];
}

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      Algorithm to select a single, random combination of values?

      您只需循环 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-12
        • 1970-01-01
        • 2012-06-08
        • 2021-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多