如何生成一个与Objective C中的前一个不同的随机数

时间:2014-03-25 12:14:51

标签: objective-c random

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

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

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

5 个答案:

答案 0 :(得分:4)

int q = (arc4random() % 4);
int i = (arc4random() % 4);
while (q == i) {
  q = (arc4random() % 4);
}

答案 1 :(得分:1)

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

例如,

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

答案 2 :(得分:1)

正如这里的一些答案所述,arc4random带有while循环,一般来说,是正确的答案,但您可能想要使用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.

答案 3 :(得分:0)

int p = (arc4random() % 4);
int q = (arc4random() % 4);
while (p == q) {
  p = (arc4random() % 4);
}

答案 4 :(得分:0)

我发现当我需要随机性时,使用协议很好,所以我可以使用不同风格的随机数生成器,但在更改生成器时不必更改任何代码。使用这种方法,您可以轻松更改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的行。