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时,它重复相同的事情。
答案 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到100之间的随机数。
此后,将3到97之间的一个随机数添加到最后一个数字,然后使用100取模,将获得1到100范围内的随机数,但不包括oldNum - 2
到oldNum + 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到100之间的随机数。
此后,默认选项是在最后一个数字后添加3到97之间的一个随机数,然后使用取模100为您获得1到100范围内的随机数,但不包括该范围内的数字oldNum - 2
至oldNum + 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
}