【问题标题】:My own random number generator我自己的随机数生成器
【发布时间】:2014-12-31 17:53:29
【问题描述】:

我想制作一个随机数生成器,用户可以在其中指定生成数字的范围和数量。我希望它使每个数字都是唯一的(不重复)。这就是我到目前为止所做的(它生成但其中一些重复,为什么?)

#include <time.h>
#include <stdio.h>
#include <windows.h>
#include <conio.h>

int main()
{
    srand(time(NULL));

    int start, stop, amount;

    system("chcp 1250 >nul");

    printf("Welcome to random number generator!\n");
    printf("\nWhat range? \nFrom: "); scanf("%i", &start);
    printf("To: "); scanf("%i", &stop);

    printf("\nHow many numbers?: "); scanf("%i", &amount);
    int number[amount];

    for(int i=0; i<amount; i++)
    {
        number[i] = rand() % ((stop+1)-start) + start;

            for(int j=i; j>-1; j--)
            {
                if(number[i]==number[j])
                {
                    number[i] = rand() % ((stop+1)-start) + start;
                }
            }

        printf("\n%i generated number: %i", i+1, number[i]);
        Sleep(10);
    }

    getch();
}

【问题讨论】:

  • 使用std::set,插入到集合中,直到其中有amount 数字。另外,使用&lt;random&gt; 而不是rand()
  • 嗯。我认为如果 OP 正在使用 printf/scanf std::set 很可能还没有被覆盖..
  • 好的,但是你能告诉我为什么我的代码不起作用吗?理论上它应该这样做。
  • @user3478487 您没有检查第二个分配是否也是重复的。如果您生成一个新号码,您必须在重新分配number[i] 后将j 重置为i-1。此外,就目前而言,您总是会重新分配一次,因为当ij 相等时,您正在比较number[i] == number[j]j 应初始化为i-1
  • 如果数字大于间隔怎么办(编辑:抱歉,Marc B. 也提到过)?另请注意,当您执行 int number[amount] 时,您依赖的是编译器扩展。

标签: c random numbers generator


【解决方案1】:

您的“检查受骗”循环不正确。您可能会找到一个重复项,但是您不会检查该重新生成的数字是否存在于您已经测试过的内容中。

例如考虑这样的数组。用户要求输入 5 个数字,范围 1-10

number[0] = 5
number[1] = 6
number[2] = 2
number[3] = 8

现在您正在处理数字[4]。您生成2...您向后扫描数组并发现2 是一个骗子。所以你生成一个新号码......并生成8。但是您不会重置您的 j 循环 - 您只是继续向后工作,并且永远不会看到 8 已经在数组中。

你应该拥有的更像是:

        for(int j=i; j>-1; j--) {
            if(number[i]==number[j]) {
                number[i] = rand() % ((stop+1)-start) + start;
                j = i; // RESET THE LOOP
            }
        }

请注意,您的代码很容易产生无限循环。例如考虑有人要求 1-3 范围内的数字,并生成其中的 4 个。 1,2,3,?。条件永远不能满足,因为你不可能有 1-3 个没有至少一个重复。

【讨论】:

  • 这是一个非常不理想的解决方案。它会起作用,但是想象一下,如果您尝试生成大量数字并且接近尾声,会发生什么。你大部分时间都在生成一个骗子并不断重复这个循环。
  • 是的,但 OP 并没有要求有效的解决方案。
  • 我只是想让他知道这一点。这可能是一个问题,尤其是对于不是真正统一的现实生活中的随机数生成器。它会在一开始就用完所有频繁的值,然后可能最终会卡住试图找到剩余的数字
  • 你需要把 j = i 改为 j = i - 1 否则这个循环永远不会结束。
【解决方案2】:

因此,即使我们假设 rand() 是一个完美的随机数生成器,数字也会重复。 假设您必须生成 100 个数字。假设您的开始 = 1,停止 = 100。

您生成从 1 到 100 的第一个数字,然后生成第二个,依此类推。到目前为止,您使用的数字越多,就越容易得到重复。

然后你会找到一个重复的内部 for 循环。您生成一个新号码 number[i],但你不能保证这个数字是唯一的。你还不如结束 将 number[i] 设置为另一个副本。

如果你想让你的代码工作,你必须不断改变 number[i] 只要它有重复。

这是关于您的代码中的错误。 另一方面,这段代码效率极低,因此如果您打算经常运行此过程,则应考虑对其进行优化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 2014-01-23
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多