如何从1到50有效地选择几个独特的随机数,不包括x?

时间:2010-03-23 18:02:06

标签: objective-c random

我有两个0到49之间的数字。我们称之为xy。现在我想得到一些不是x或y的其他数字,但也在049之间(我使用的是Objective C但是这更像是一个普遍的理论问题吗? )。

我想到的方法是:

 int a;
 int b;
 int c;

 do {
  a = arc4random() % 49;
 } while ((a == x) || (a == y));

 do {
  b = arc4random() % 49;
 } while ((b == x) || (b == y) || (b == a));

 do {
  c = arc4random() % 49;
 } while ((c == x) || (c == y) || (c == a) || (c == b));

但这对我来说似乎有点不好,我不知道,我只是想学习成为一名更优秀的程序员,最优秀的做法是什么?

5 个答案:

答案 0 :(得分:9)

您可以使用名为Fisher-Yates shuffle的内容。这是一种从一些集合中生成随机排序的值列表的有效算法。您首先要从获取随机值的值列表中排除N,然后执行随机播放。

答案 1 :(得分:5)

你应该在你的情况下改变一组数字(值为[0,...,49];如果你已经知道它们,你也可以从那个数组中排除你的xy值),然后从混洗数组中获取前N个值(无论你寻求多少)。这样,所有数字都是该范围的随机数,而不是“之前见过的”。

答案 2 :(得分:1)

我会做更多的事情:

NSMutableSet * invalidNumbers = [NSMutableSet set];
[invalidNumbers addObject:[NSNumber numberWithInt:x]];
[invalidNumbers addObject:[NSNumber numberWithInt:y]];

int nextRandom = -1;
do {
  if (nextRandom >= 0) {
    [invalidNumbers addObject:[NSNumber numberWithInt:nextRandome]];
  }
  nextRandom = arc4random() % 49;
} while ([invalidNumbers containsObject:[NSNumber numberWithInt:nextRandom]]);

答案 3 :(得分:0)

您可以将x,y和新数字添加到可用作set的数据结构中并执行类似操作(在伪代码中; set结构需要类似{{{ 1}}添加值和push以检查成员资格):

in

所以如果objc有适当的东西,这很容易...... [啊哈,确实如此,见Dave DeLong的帖子]。

如果number_of_randoms远小于49,则该算法有意义;如果它们具有可比性,那么你应该采用一种改组(又名置换)的想法。

答案 4 :(得分:0)

首先,制作一组有效数字:

// Create a set of all the possible numbers
NSRange range = { 0, 50 };// Assuming you meant [0, 49], not [0, 49)
NSMutableSet *numbers = [NSMutableSet set];
for (NSUInteger i = range.location; i < range.length; i++) {
    NSNumber *number = [NSNumber numberWithInt:i];
    [numbers addObject:number];
}

// Remove the numbers you already have
NSNumber *x = [NSNumber numberWithInt:(arc4random() % range.length)];
NSNumber *y = [NSNumber numberWithInt:(arc4random() % range.length)];
NSSet *invalidNumbers = [NSSet setWithObjects:x, y, nil];
[numbers minusSet:invalidNumbers];

然后,如果您不需要保证数字是随机的,您可以使用-anyObject-removeObject来提取其他几个数字。如果您确实需要它们是随机的,请按照LBushkin's answer进行操作,但请注意不要意外实施Sattolo's algorithm

// Shuffle the valid numbers
NSArray *shuffledNumbers = [numbers allObjects];
NSUInteger n = [shuffledNumbers count];
while (n > 1) {
    NSUInteger j = arc4random() % n;
    n--;
    [shuffledNumbers exchangeObjectAtIndex:j withObjectAtIndex:n];
}