1

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

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

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

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

3 回答 3

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];
于 2012-11-11T16:39:24.647 回答
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;
        }
    }
}

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

于 2012-11-11T16:31:42.997 回答
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;
}
于 2017-10-10T13:32:51.777 回答