不要在C +-2中生成相同的随机数

时间:2019-05-03 19:41:31

标签: c random numbers srand

srand(time(NULL));

for(i = 0; i < 100; i++)
{
   int randomNumber = (rand() % 100) + 1  // gets a random number from 0 - 100.
   // do stuff
}

我目前有一个随机数变量,它在for循环的每次迭代中存储一个0-100的数字,然后下面的代码填充该随机数变量。但是我注意到,每次循环迭代时,有时会生成相同的随机数,而有时它会生成一个非常接近于我已经生成的数字。例如:何时
i = 1的randomNumber可能是50,但是当i = 2的时候,它可能是51。这对于我正在编码的东西来说非常令人讨厌。有没有一种方法可以使它做到,如果它第一次生成50,那么第二次它必须生成一个比刚刚生成的整数大2的整数。例如。如果它只生成50,则第二次它不能生成48、49、50、51、52,但是它仍然生成0-100之间的值,只是跳过这些数字。然后,当生成新的randomNumber时,它重复相同的事情。

2 个答案:

答案 0 :(得分:2)

最简单的方法是在循环中获取随机数,以检查随机数是否与最后一个数字过于接近。

srand(time(NULL));
int lastRandom = -2;
for(int i = 0; i < 100; i++)
{
    int randomNumber;
    do {
        randomNumber = (rand() % 100) + 1;  // gets a random number from 0 - 100.
    } while (randomNumber >= lastRandom - 2 && randomNumber <= lastRandom + 2);
    lastRandom = randomNumber;
    // do stuff
}

通常我不建议循环调用rand(),因为如果接受标准太严格,这可能会持续太长时间。但这仅拒绝了5%,因此不太可能重复多次。

答案 1 :(得分:1)

如果您不介意多次获得相同的数字(只要它不是连续的),但又不想让内环尝试获取新的数字,您可能会做的事情是:

  1. 通常在第一个循环中获取1到100之间的随机数。

  2. 此后,将3到97之间的一个随机数添加到最后一个数字,然后使用100取模,将获得1到100范围内的随机数,但不包括oldNum - 2oldNum + 2

    (请注意,这包装了排除数字的范围,因此,例如,如果最后一个数字是100,则还将排除1和2)。

srand(time(NULL));

int randomNumber;
for(i = 0; i < 100; i++) {
   if (i == 0) {
       randomNumber = (rand() % 100) + 1;  // gets a random number from 1 - 100.
   } else {
       randomNumber = ((randomNumber + (rand() % 95) + 3) % 100) + 1;
   }
   // do stuff
}

如果您不希望包装要排除的号码列表(例如,如果最后一个号码是99,则只希望排除97、98、99和100),则它会稍微复杂一些:

  1. 您仍然希望在第一个循环中通常获得1到100之间的随机数。

  2. 此后,默认选项是在最后一个数字后添加3到97之间的一个随机数,然后使用取模100为您获得1到100范围内的随机数,但不包括该范围内的数字oldNum - 2oldNum + 2

    但是在使用默认选项之前,您需要检查旧数字是否太低或太高,以至于排除数字的范围会环绕:

    a。如果旧数字太低,以至于排除数字的范围会自动换行,那么我们想要一个从oldNum + 3到100范围内的随机数字。

    b。如果旧数字太高了,以至于排除数字的范围会自动换行,那么我们想要一个从1到oldNum - 3范围内的随机数字。

srand(time(NULL));

int randomNumber;
for(i = 0; i < 100; i++) {
   if (i == 0) {
       randomNumber = (rand() % 100) + 1;  // gets a random number from 1 - 100.
   } else {
        if (randomNumber < 3) {
        /* Old number is so low that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from randomNumber + 3 to 100:
         */
            randomNumber += (rand() % (98 - randomNumber)) + 3; 
        }
        else if (randomNumber > 98) {
        /* Old number is so high that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from 1 to randomNumber - 3:
         */
            randomNumber = (rand() % (randomNumber - 3)) + 1; 
        } else {
        /* Default way. 
         * We want a random number in the range 1 to 100, excluding numbers in the 
         * range randomNumber - 2 to randomNumber + 2
         */
            randomNumber = ((randomNumber + (rand() % 95) + 3) % 100) + 1;
        }
   }
   // do stuff
}

如果有人遇到相同的问题,但希望数字在不同范围内和/或希望排除数字的范围不同,那么这里的代码相同,但用常量代替“魔术数字”:

srand(time(NULL));

int randomNumber;
int const maxNum = 100; // Random number must be in the range from 1 to maxNum
int const exclude = 2;  // New random number must NOT be in the range
                        // from (oldNum - exclude) to (oldNum + exclude)
for(i = 0; i < 100; i++) {
   if (i == 0) {
       randomNumber = (rand() % maxNum) + 1;  // gets a random number from 1 to maxNum.
   } else {
        if (randomNumber <= exclude) {
        /* Old number is so low that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from (randomNumber + exclude + 1)
         * to maxNum:
         */
            randomNumber += (rand() % (maxNum - exclude - randomNumber)) + exclude + 1; 
        }
        else if (randomNumber > maxNum - exclude) {
        /* Old number is so high that excluded numbers would wrap if we would
         * be using the 'default' way.
         * We want a random number in the range from 1 to (randomNumber - exclude - 1):
         */
            randomNumber = (rand() % (randomNumber - exclude - 1)) + 1; 
        } else {
        /* Default way. 
         * We want a random number in the range 1 to 100, excluding numbers in the 
         * range randomNumber - exclude to randomNumber + exclude
         */
            randomNumber = ((randomNumber + (rand() % (maxNum - 2*exclude - 1) 
                    + exclude + 1) % maxNum) + 1;
        }
   }
   // do stuff
}