iOS:我如何生成8个独特的随机整数?

我需要生成8个随机整数,但它们需要是唯一的,又不是重复的。

例如,我想要在8到1范围内的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; } 

 -(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; } 

唯一性是你需要提供的 – 随机性的API不会为你做这个。

如上所述,您可以生成一个数字,然后检查它是否与已经生成的数据相冲突,如果是,请尝试一下。 但请注意,根据数量和范围的大小,这成为一个没有保证终点的algorithm。

如果你真的只是试图以随机的顺序获得一组连续的数字,这是不是这样做,因为它可能需要很长的时间才能完成。 在这种情况下,首先构build一个所有期望值的数组,然后“洗牌”数组是一个更好的select。 最好的洗牌是Fisher-Yates ,但是如果你不需要完全没有偏见的话,你也可以做这里描述的。

检查已经产生的数字可能是昂贵的(理论上,这可能需要永远)。但是,这是一个解决的问题。 你需要一个洗牌algorithm,比如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 

将数字存储在一个数组中,并且每次生成下一个数字时,检查它是否已经存在于数组中。 如果不是,则添加并继续。

这是一些伪代码

  1. 对于每个号码1-8产生一个随机数字。
  2. 将随机数和整数作为键值对添加到字典中
  3. 获取字典的所有键作为数组(提示:看看allKeys方法)
  4. sorting这个数组(升序或降序不重要)
  5. 现在以这些数字中的每一个为关键字,从字典中获取相应的整数

试试这个代码…这将给你所有可能的唯一数字设置在可变数组中…

 -(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; }