我正在使用rand()
需要唯一值的 6 位字段。我做对了吗?
有多少几率,rand()
可以在连续或频繁调用时给我类似的值?
当我使用 rand() 时,它是独一无二的。但是,当我调用srand(time(NULL))
or 时返回了相同的号码srand(clock())
。似乎,它对我来说是相反的。或者是吗?
我正在使用rand()
需要唯一值的 6 位字段。我做对了吗?
有多少几率,rand()
可以在连续或频繁调用时给我类似的值?
当我使用 rand() 时,它是独一无二的。但是,当我调用srand(time(NULL))
or 时返回了相同的号码srand(clock())
。似乎,它对我来说是相反的。或者是吗?
rand()
返回 0 和 之间的值RAND_MAX
。由于它是离散的均匀分布,RAND_MAX
因此重复数字的概率为 1/( +1),因此无法保证唯一性。
srand(seed)
初始化您的随机数生成器,以便每次从中获得的数字序列rand()
都是相同的,因为您每次都对其进行初始化seed
。
在您的示例seed = time(NULL)
中,这是从 1970 年 1 月 1 日开始经过的秒数,因此确保了不同的种子,因此每次调用都有不同的随机数序列srand(time(NULL))
(假设它不是在同一秒内进行的)。
正如其他人指出的那样,不能保证唯一性。但是,您可能会看到重复的数字,因为您错误地使用了 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
.
随机数是随机的,不是唯一的。就像掷骰子的情况一样,当你可以连续掷出几个六时,你rand
可以(并且应该)有时会给你相同的数字。
为了确保数字是唯一的,请构建一个集合,在其中注册您已经添加的每个数字。当一个随机数出现不止一次时,扔掉第二个,然后去寻找下一个。
rand() 在连续或频繁调用时可以给我类似的值的几率是多少?
的算法rand
在 C 中未指定。返回的数字的随机性质量也是如此rand
。