【问题标题】:Don't Generate Same Random Number in C +- 2不要在 C++ 2 中生成相同的随机数
【发布时间】:2019-05-03 19:41:30
【问题描述】:
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 时重复同样的事情。

【问题讨论】:

  • 所以只要循环,直到你有一个合适的数字。
  • 如果你需要 100 个介于 1 和 100 之间的数字而不被欺骗,用 1-100 填充一个数组并随机播放。
  • 代码(最初)生成从 1 到 100 的数字,但注释说 0 到 100。需要哪个?
  • @EricPostpischil 他甚至还没有登上飞往这个国家的飞机,说出他真正想做的事情。他什么也没说,只是“我有这个号码,它的行为方式是这样的,我希望它也有这样的行为方式”。 为什么他想要那个?他是在试图展示看起来随机的点吗?他是否试图选择半随机问题进行测验?他是在试图改变音乐选择吗?这就是我们需要知道的帮助。
  • @LeeDanielCrocker:一些确认和澄清会有所帮助,但很可能请求是从 [1, 100] 中整数的均匀分布中抽取第一个样本,然后从 [1, 100] 中抽取后续样本[1, 100]−[x-2, x+2] 中整数的均匀分布,其中 x 是前一个样本。无论如何,您关于属性“恰好是随机数的属性”的说法是错误的且无益的。

标签: c random numbers srand


【解决方案1】:

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

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%,因此不太可能重复多次。

【讨论】:

  • 添加了来自原始代码的缺失的;
【解决方案2】:

如果您不介意多次获取相同的数字(只要它不在一行中),但您不希望内部循环尝试获取新数字,您可能会做的是:

  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 - 2 范围内的数字到oldNum + 2

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

    一个。如果旧数字太小以至于排除数字的范围会换行,那么我们想要一个范围从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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2013-12-10
    • 2017-07-30
    相关资源
    最近更新 更多