2

我正在使用rand()需要唯一值的 6 位字段。我做对了吗?

有多少几率,rand()可以在连续或频繁调用时给我类似的值?

当我使用 rand() 时,它是独一无二的。但是,当我调用srand(time(NULL))or 时返回了相同的号码srand(clock())。似乎,它对我来说是相反的。或者是吗?

4

4 回答 4

3

rand()返回 0 和 之间的值RAND_MAX。由于它是离散的均匀分布,RAND_MAX因此重复数字的概率为 1/( +1),因此无法保证唯一性。

srand(seed)初始化您的随机数生成器,以便每次从中获得的数字序列rand()都是相同的,因为您每次都对其进行初始化seed

在您的示例seed = time(NULL)中,这是从 1970 年 1 月 1 日开始经过的秒数,因此确保了不同的种子,因此每次调用都有不同的随机数序列srand(time(NULL))(假设它不是在同一秒内进行的)。

于 2012-09-13T18:03:01.110 回答
3

正如其他人指出的那样,不能保证唯一性。但是,您可能会看到重复的数字,因为您错误地使用了 srand() 和 rand()。

srand() 用于播种随机数生成器。这意味着在调用 srand 之后对 rand() 的一系列调用将产生一系列特定的值。如果您使用相同的值调用 srand() ,则 rand() 将产生相同系列的值(对于给定的实现,不同实现之间无法保证)

int main() {
    srand(100);
    for(int i = 0; i<5; ++i)
        printf("%d\n",rand());

    printf("\nreset\n\n");

    srand(100);
    for(int i = 0; i<5; ++i)
        printf("%d\n",rand());

}

对我来说,这会产生:

365
1216
5415
16704
24504

reset

365
1216
5415
16704
24504

time() 和 clock() 返回时间,但如果你调用它们的速度足够快,那么返回的值将是相同的,所以你会从 rand() 中得到相同的一系列值。

此外 rand() 通常不是一个很好的随机数生成器,使用它通常意味着您必须将一系列数字转换为您实际需要的分布。你应该找到一个不同的随机源,要么学习正确的方法来产生你想要的分布,要么使用一个可以为你做的库。(例如,一种在 0 和 N 之间产生“随机”数的常用方法是这样做rand() % N,但这并不是最好的方法。

C++ 在<random>. 它提供了不同的 PRNG 算法,例如 linear_congruential、mersenne_twister,甚至可能提供加密安全的 RNG(取决于实现)。它还提供了用于生成各种分布的对象,例如应避免在rand() % N.

于 2012-09-13T18:07:20.877 回答
2

随机数是随机的,不是唯一的。就像掷骰子的情况一样,当你可以连续掷出几个六时,你rand可以(并且应该)有时会给你相同的数字。

为了确保数字是唯一的,请构建一个集合,在其中注册您已经添加的每个数字。当一个随机数出现不止一次时,扔掉第二个,然后去寻找下一个。

于 2012-09-13T18:04:21.720 回答
0

rand() 在连续或频繁调用时可以给我类似的值的几率是多少?

的算法rand在 C 中未指定。返回的数字的随机性质量也是如此rand

在此处输入图像描述

于 2012-09-13T18:14:31.550 回答