【问题标题】:How to generate a random number which is different from the previous one in Objective C [duplicate]如何在Objective C中生成一个与前一个不同的随机数[重复]
【发布时间】:2014-03-25 12:14:50
【问题描述】:

我有一个从 (arc4random() % 4) 生成的 int i,然后我从另一个 (arc4random() % 4) 创建了一个新的氡气 int q,我希望生成 q 直到它与 i 不同。

例如,如果 i = 2,则 q 必须为 0、1、3。

我该怎么做?是否可以应用循环或条件? 谢谢

【问题讨论】:

    标签: objective-c random


    【解决方案1】:
    int q = (arc4random() % 4);
    int i = (arc4random() % 4);
    while (q == i) {
      q = (arc4random() % 4);
    }
    

    【讨论】:

    • 我没有注意到这种“反向”方式,非常感谢!
    【解决方案2】:

    使用while循环并存储之前的结果。

    例如,

    int previous = (arc4random() % 4);
    int current = (arc4random() % 4);
    while(current  == previous)
    {
     current = (arc4random() % 4);
    }
    

    【讨论】:

      【解决方案3】:

      正如这里的一些答案所述,带有 while 循环的 arc4random 通常是正确答案,但您可能希望使用 arc4random_uniform(x),因为它可以避免模数偏差。

      来自文档:

      arc4random_uniform() will return a uniformly distributed random number less than upper_bound.
      arc4random_uniform() is recommended over constructions like ``arc4random() % upper_bound'' as it
      avoids "modulo bias" when the upper bound is not a power of two.
      

      【讨论】:

        【解决方案4】:
        int p = (arc4random() % 4);
        int q = (arc4random() % 4);
        while (p == q) {
          p = (arc4random() % 4);
        }
        

        【讨论】:

          【解决方案5】:

          我发现当我需要随机性时,使用协议很好,这样我就可以拥有不同风格的随机数生成器,而在更改生成器时不必更改任何代码。通过这种方法,您可以轻松更改 RNG 的特征。

          如果你想在所有数字都用完之前防止重复,你可以用一个打乱值的类来代替,然后提供它们直到它们消失……再次打乱……等等。当然,这种方法只是如果您有少量可能的值,则可以使用。对于更大的值,需要使用概率方法。

          你会在某个地方有这个协议......

          @protocol RandomNumberGenerator <NSObject>
          - (uint32_t)randomNumber;
          @end
          

          然后你可以有这个类,它提供了协议的特定实现......

          @interface NonRepeatingRandomNumberGenerator : NSObject<RandomNumberGenerator>
          - (instancetype)init;
          - (instancetype)initWithUpperBound:(uint32_t)upperBound;
          - (uint32_t)randomNumber;
          @end
          
          @implementation NonRepeatingRandomNumberGenerator {
              uint32_t lastNumber_;
              uint32_t *upperBound_;
          }
          
          - (instancetype)init
          {
              if (self = [super init]) {
                  lastNumber_ = arc4random();
                  upperBound_ = NULL;
              }
              return self;
          }
          
          - (instancetype)initWithUpperBound:(uint32_t)upperBound
          {
              if (self = [super init]) {
                  lastNumber_ = arc4random_uniform(upperBound);
                  upperBound_ = malloc(sizeof(*upperBound_));
                  *upperBound_ = upperBound;
              }
              return self;
          }
          
          - (void)dealloc
          {
              free(upperBound_);
          }
          
          - (uint32_t)randomNumber
          {
              uint32_t result;
              do {
                  result = upperBound_ ? arc4random_uniform(*upperBound_) : arc4random();
              } while (result != lastNumber_);
              lastNumber_ = result;
              return result;
          }
          @end
          

          然后使用,您可以使 RNG 成为您的类的属性,或者以其他方式使其普遍可用...

          self.randomGenerator = [NonRepeatingRandomNumberGenerator initWithUpperBound:4];
          

          以后,随便找个随机数……

          randomNumber = [self.randomGenerator randomNumber];
          

          如果您决定更改生成数字的方式,只需替换创建 RNG 的行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-04-22
            • 1970-01-01
            • 2019-02-10
            • 2020-01-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-06-29
            相关资源
            最近更新 更多