关于视觉c:C随机数生成器,无需重复数字

C++ random number generator without repeating numbers

我在上下搜索了一种可以转换此代码的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

void ran(int array[], int max);
int main() {
 printf("Today's lottery numbers are:\
"
);    
 for (int i = 0; i < 6; i++)
  srand((unsigned)(NULL));
}

进入随机数生成器,以确保没有重复的数字有人可以帮助我吗?检查后,我打算用printf("%d\
", rand()%50);

打印

我只需要一个确保不重复的例程即可。请您给我一个例行程序,这会让我很放心,并且一定会付给我的。

谢谢。这些库似乎无法正确读取,但它们是stdio,stdlib,time和im,它们使用名称空间。


为什么不仅仅使用STL中已经存在的内容?查看您的示例代码,并假设它在某种程度上代表了您要执行的操作,那么所有内容都应该放在其中。 (我假设您需要相对较小的数字范围,因此内存不会受到限制)。

使用std::random_shufflestd::vector包含您希望数字位于的范围内的整数,应该为您提供示例代码中所需的唯一的随机数序列。

在使用std::random_shuffle之前,您仍然必须一次调用srand。在您当前的代码示例中,没有像您所做的那样多次。


如果您的随机数范围有限且很小,请说您有X个不同的数。

  • 用每个数字创建一个数组
  • 在0到X之间选择一个随机索引I,并获取其值
  • X值移到I位置
  • 减少X并重复

您仅应在代码中调用一次srand,并且应使用" random "种子(如time(NULL))来调用它。

通过在循环中调用srand,并每次以0种子进行调用,您将获得六个完全相同的数字。

但是,即使进行了这些修复,rand()%50也可能给您两次相同的数字。您应该使用的是这种洗牌算法,因为它的工作原理与彩票机完全相同。

这是一个完整的程序,显示正在执行的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static void getSix (int *dst) {
    int sz, pos, i, src[50];
    for (i = 0; i < sizeof(src)/sizeof(*src); i++)
        src[i] = i + 1;
    sz = 50;
    for (i = 0; i < 6; i++) {
        pos = rand() % sz;
        dst[i] = src[pos];
        src[pos] = src[sz-1];
        sz--;
    }
}
int main (void) {
    srand (time (NULL));
    int i, numbers[6];
    getSix (numbers);
    printf ("Numbers are:\
"
);
    for (i = 0; i < sizeof(numbers)/sizeof(*numbers); i++)
        printf ("   %d\
"
, numbers[i]);
    return 0;
}

样品运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Numbers are:
   25
   10
   26
   4
   18
   1
Numbers are:
   39
   45
   8
   18
   17
   22
Numbers are:
   8
   6
   49
   21
   40
   28
Numbers are:
   37
   49
   45
   43
   6
   40

我建议使用更好的随机数生成算法,该算法可以在内部提供,而不要使用rand。

rand()并试图防止重复的问题是,将每个数字添加到已用列表中后,找到未使用的数字将变慢,最终成为查找和丢弃数字的漫长过程。

如果您要使用更复杂的伪随机数生成器(并且有很多可用的,请检查Boost几个),那么您的时间将会更轻松,并且可以完全避免重复。它取决于算法,因此您需要检查文档。

要在不使用任何其他库的情况下执行此操作,可以使用顺序(甚至随机)数字预填充矢量或列表,并确保每个数字在列表中一次出现。然后,要生成一个数字,请生成一个随机数,然后从列表中选择(并删除)该项目。只要删除每个使用的项目,只要每个项目都存在一次,就永远不会出现重复项。


如果您有权使用C 0x,则可以使用新的随机生成器功能来为您包装所有垃圾!

http://www2.research.att.com/~bs/C 0xFAQ.html#std-random