10

我需要生成 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;
}
4

6 回答 6

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;
}
于 2011-05-27T14:32:10.050 回答
9

唯一性是您需要提供的东西——随机性 API 不会为您做到这一点。

正如建议的那样,您可以生成一个数字,然后检查它是否与您已经生成的内容发生冲突,如果是,请尝试 agin。但是请注意,根据数字的数量和范围的大小,这将成为一种没有保证终点的算法。

如果您真的只是想以随机顺序获取一组连续的数字,那么这不是一种方法,因为它可能需要很长时间才能完成。在这种情况下,首先构建一个包含所有所需值的数组,然后“改组”该数组是更好的选择。最好的洗牌是Fisher-Yates,但如果您不需要它完全不偏不倚,您也可以执行此处描述的操作。

于 2011-05-27T14:24:45.960 回答
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
于 2011-05-27T14:44:46.437 回答
2

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

于 2011-05-27T14:19:29.220 回答
1

这是一些伪代码

  1. 为每个数字 1-8 生成一个随机数。
  2. 将随机数和整数作为键值对添加到字典中
  3. 将字典的所有键作为数组获取(提示:查看allKeys方法)
  4. 对该数组进行排序(升序或降序并不重要)
  5. 现在将这些数字中的每一个作为键,从字典中获取相应的整数
于 2011-05-27T14:23:39.413 回答
0

试试这个代码......这将为您提供在可变数组中设置的所有可能的唯一数字......

-(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; 
}
于 2015-08-05T12:08:44.500 回答