我正在使用rand()
作为需要唯一值的6位字段。我做得对吗?
有多少赔率,rand()
可以在连续或频繁的通话中给我类似的值?
当我使用rand()时它是独一无二的。但是,当我拨打srand(time(NULL))
或srand(clock())
时,返回相同的号码。似乎,就像它对我而言正好相反。或者是吗?
答案 0 :(得分:3)
rand()
返回0到RAND_MAX
之间的值。由于它是离散的均匀分布,因此重复数字的概率为1 /(RAND_MAX
+ 1),因此无法保证唯一性。
srand(seed)
初始化您的随机数生成器,以便每次使用rand()
初始化时,seed
从srand(time(NULL))
获得的数字序列相同。
在你的示例seed = time(NULL)
中,这是从1970年1月1日起经过的秒数,从而确保了不同的种子,因此每次调用{{1}}时都会有不同的随机数序列(假设它是不是在同一秒内制作的。)
答案 1 :(得分: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,mersennne_twister,甚至可能是加密安全的RNG(取决于实现)。它还提供了用于生成各种分布的对象,例如uniform_int_distribution,它应该避免rand() % N
中的错误。
答案 2 :(得分:2)
随机数是随机,而不是唯一。就像掷骰子的情况一样,你可以连续掷几个六,你的rand
可以(而且应该)给你一些相同的数字。
为了确保这些数字是唯一的,建立一个集合,您可以在其中注册已添加的每个数字。当一个随机数出现不止一次时,扔掉第二个,然后去下一个。
答案 3 :(得分:0)
什么是赔率,rand()可以在连续或频繁的通话中给我类似的值?
rand
的算法在C中未指定。因此rand
返回的数字的随机性质量。