C++产生随机数,我们都知道,无非就是利用srand产生一个种子,然后利用rand函数产生随机数即可。但是今天在产生随机数的时候遇到了一个怪事,就是不管自己怎么产搞,多次产生的随机数都是重复的。自己的代码简化为下:
#include "stdafx.h"
#include <cstdlib>
#include <ctime>
#include <iostream>
class RandomNum
{
public:
void creataRandomNum()
{
srand(unsigned(time(NULL)));
std::cout << rand()<< std::endl;
}
};
int main()
{
for (int i=0;i<5;i++)
{
RandomNum random_num;
random_num.creataRandomNum();
}
}
很简单,就是在一个类中,有一个函数,在这个函数中产生随机数然后输出,来看一下输出的结果:
对的,你没看错,虽然设置了种子,但是输出的随机数是唯一的(不设置种子输出的随机数也是唯一的,有兴趣的话可以试一试)。
我们知道,srand()用来设置rand()产生随机数时的随机数种子。在调用rand()函数产生随机数前,必须先利用srand()设好随机数种子(seed), 如果未设随机数种子, rand()在调用时会自动设随机数种子为1(这也就是当我们不设置种子时,每次程序运行都会产生同样的随机数的原因)。进一步分析,我们在类里面调用产生随机数的函数以及设置种子的函数,那只要你的电脑足够好,程序运行的足够快,循环的每次(或者准确的说是前几次)每次srand()函数中获取的系统时间都是一致的,那么执行每次rand函数之前,设置的种子都一样,就和没设置种子一样了,这样导致了产生的随机数就是一样的。
那解决办法其实很简单,就是不要将srand函数放在类的函数内部,最好把它放在主函数中,这样就相当于设置了一次种子,但是产生了多次随机数。而不是像上面的代码一样,每次设置一次种子,产生一次随机数,然后设置的种子还一样,产生的随机数当然一样了。
修改后的代码如下:
#include "stdafx.h"
#include <cstdlib>
#include <ctime>
#include <iostream>
class RandomNum
{
public:
void creataRandomNum()
{
std::cout << rand()<< std::endl;
}
};
int main()
{
srand(unsigned(time(NULL)));
for (int i=0;i<5;i++)
{
RandomNum random_num;
random_num.creataRandomNum();
}
}
看结果,产生的随机数已经正常了。
当然,在C++11中,已经有产生随机数的函数random,用法如下:
#include "stdafx.h"
#include <iostream>
#include <random>
int main()
{
std::default_random_engine e;
for (size_t i = 0; i < 5; ++i) //生成五个随机数
std::cout << e() << std::endl;
std::cout << "Min random:" << e.min() << std::endl; //输出该随机数引擎序列的范围
std::cout << "Max random:" << e.max() << std::endl;
return 0;
}
这种方式产生的随机数更好,如果能用这种方式的话,就尽量使用这种吧。