我需要生成8个随机整数,但它们必须是唯一的,也就是说不重复。
例如,我想要1到8范围内的8个数字。
我见过arc4random,但我不确定如何让它们与众不同?
解决方案
-(NSMutableArray *)getRandomInts:(int)amount from:(int)fromInt to:(int)toInt {
if ((toInt - fromInt) +1 < amount) {
return nil;
}
NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
int r;
while ([uniqueNumbers count] < amount) {
r = (arc4random() % toInt) + fromInt;
if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
[uniqueNumbers addObject:[NSNumber numberWithInt:r]];
}
}
return uniqueNumbers;
}
答案 0 :(得分:14)
-(NSMutableArray *)getEightRandom {
NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
int r;
while ([uniqueNumbers count] < 8) {
r = arc4random();
if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
[uniqueNumbers addObject:[NSNumber numberWithInt:r]];
}
}
return uniqueNumbers;
}
如果要限制为小于某个阈值M的数字,则可以通过以下方式执行此操作:
-(NSMutableArray *)getEightRandomLessThan:(int)M {
NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
int r;
while ([uniqueNumbers count] < 8) {
r = arc4random() % M; // ADD 1 TO GET NUMBERS BETWEEN 1 AND M RATHER THAN 0 and M-1
if (![uniqueNumbers containsObject:[NSNumber numberWithInt:r]]) {
[uniqueNumbers addObject:[NSNumber numberWithInt:r]];
}
}
return uniqueNumbers;
}
如果M = 8,或者即使M接近8(例如9或10),那么这需要一段时间,你可以更聪明。
-(NSMutableArray *)getEightRandomLessThan:(int)M {
NSMutableArray *listOfNumbers = [[NSMutableArray alloc] init];
for (int i=0 ; i<M ; ++i) {
[listOfNumbers addObject:[NSNumber numberWithInt:i]]; // ADD 1 TO GET NUMBERS BETWEEN 1 AND M RATHER THAN 0 and M-1
}
NSMutableArray *uniqueNumbers = [[[NSMutableArray alloc] init] autorelease];
int r;
while ([uniqueNumbers count] < 8) {
r = arc4random() % [listOfNumbers count];
if (![uniqueNumbers containsObject:[listOfNumbers objectAtIndex:r]]) {
[uniqueNumbers addObject:[listOfNumbers objectAtIndex:r]];
}
}
[listOfNumbers release];
return uniqueNumbers;
}
答案 1 :(得分:9)
您需要提供唯一性 - 随机API不会为您执行此操作。
如上所述,您可以生成一个数字,然后检查它是否与您已生成的内容发生冲突,如果是,请尝试使用agin。但请注意,根据数量和范围的大小,这将成为一个没有保证终点的算法。
如果您真的只是想在随机订单中获取一组连续的数字,那么这不是一种方法,因为它可能需要不可预测的长时间才能完成。在这种情况下,首先构建一个包含所有所需值的数组,然后“改组”数组是一个更好的选择。最好的洗牌是Fisher-Yates,但是如果你不需要它完全不偏不倚,你也可以做here所描述的内容。
答案 2 :(得分:7)
检查已生成的数字可能很昂贵(理论上,它可能需要永远。)但是,这是一个已解决的问题。你想要一个改组算法,比如Fisher-Yates_shuffle
在iOS上可能是这样的:
NSMutableArray *randSequence = [[NSMutableArray alloc] initWithCapacity:8];
for (int ii = 1; ii < 9; ++ii)
[randSequence addObject:[NSNumber numberWithInt:ii]];
for (int ii = 8; ii > 0; --ii) {
int r = arc4random() % (ii + 1);
[randSequence exchangeObjectAtIndex:ii withObjectAtIndex:r];
// you can now iterate over the numbers in `randSequence` to get
// your sequence in random order
答案 3 :(得分:2)
将数字存储在一个数组中,每次生成下一个数字时 - 检查数组中是否已存在。如果没有,则添加并继续。
答案 4 :(得分:1)
这是一些伪代码
allKeys
方法)答案 5 :(得分:0)
尝试使用此代码...这将为您提供Mutable数组中设置的所有唯一编号...
-(NSInteger) randomNumber {
NSInteger newRandomNumber = (NSInteger) arc4random() % 10;
NSInteger uniqueNumber;
if ([self.arrayContainingNumbers containsObject: [NSNumber numberWithInteger:newRandomNumber]]) {
[self randomNumber];
} else {
[self.arrayContainingNumbers addObject: [NSNumber numberWithInteger:newRandomNumber]];
}
uniqueNumber = [[self.mutableArrayContainingNumbers lastObject]integerValue];
NSLog(@"new Unique Number is %ld",(long)uniqueNumber);
return uniqueNumber;
}
不要忘记添加此方法:)
-(NSMutableArray *) arrayContainingNumbers {
if (!_mutableArrayContainingNumbers) {
_mutableArrayContainingNumbers = [[NSMutableArray alloc] init];
}
return _mutableArrayContainingNumbers;
}