obj-c:从范围内生成随机数,不包括变量2

时间:2012-11-11 16:10:21

标签: objective-c cocos2d-iphone

我在0和topOfRange之间生成一个随机数。我可以使用以下代码排除firstNumberToExclude:

NSInteger aRandom;
while ((aRandom = arc4random()%topOfRange) == firstNumberToExclude);

如果要排除两个数字怎么样:firstNumberToExclude和secondNumberToExclude?这是我的计划,但似乎不合适:

NSInteger aRandom = arc4random()%topOfRange;
while (aRandom == firstNumberToExclude || aRandom == secondNumberToExclude)
    {
    aRandom = arc4random()%topOfRange;
    }

3 个答案:

答案 0 :(得分:3)

如果您将其重构为实用程序方法,我认为您的代码会更清晰,更易于维护:

+ (NSInteger)generateRandomExcluding:(NSArray *)exclude topOfRange:(NSInteger)topOfRange {
    NSInteger aRandom = arc4random_uniform(topOfRange);
    while ([exclude containsObject:[NSNumber numberWithInteger:aRandom]]) {
        aRandom = arc4random_uniform(topOfRange);
    }
    return aRandom;
}

然后你可以这样称呼它:

NSNumber *excludeOne = [NSNumber numberWithInt:5];
NSNumber *excludeTwo = [NSNumber numberWithInt:13];

NSInteger random = [MyClass generateRandomExcluding:[NSArray arrayWithObjects:excludeOne, excludeTwo, nil] topOfRange:100];

答案 1 :(得分:0)

试试这个:

NSInteger aRandom = arc4random()%topOfRange;
NSMutableArray *exludedNumbers = [NSMutableArray arrayWithObjects:
    [NSNumber numberWithInt: firstNumberToExclude],
    [NSNumber numberWithInt: secondNumberToExclude],
    nil];
BOOL flag = YES;
while (flag)
{
    flag = NO;
    for (NSNumber *numberToExclude in excludedNumbers)
    {
        if (numberToExclude.intValue == aRandom)
        {
            flag = YES;
            aRandom = arc4random()%topOfRange;
            break;
        }
    }
}

因此您可以动态添加和删除数字以从数组

中排除

答案 2 :(得分:0)

最近遇到了这个解决方案。我认为while循环是一个非常糟糕的主意,随机数字,你不能真正知道需要多长时间。所以我再次尝试并采用了其他解决方案。

在考虑排除数字池的情况下生成随机数,然后检查该数字是否大于任何排除的数字,并为每个数字增加1。

- (NSInteger) randomNumberExcluding:(NSArray <NSNumber *> *) excludedNumbers range:(NSRange) range
{
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"integerValue >= %d AND integerValue =< %d", range.location, NSMaxRange(range)];
    NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"integerValue" ascending:YES];
    excludedNumbers = [[excludedNumbers filteredArrayUsingPredicate:pred] sortedArrayUsingDescriptors:@[sorter]];
    NSInteger base = arc4random_uniform((uint32_t)(range.length - excludedNumbers.count + 1)) + (NSInteger)range.location;
    for (NSNumber *excludedNumber in excludedNumbers) {
        if (base >= excludedNumber.integerValue) {
            base++;
        }
    }
    return base;
}