百度百科给出的随机数的定义是:“随机数是专门的随机试验的结果”。当我们需要完成一个类似于抽奖的程序时,我们往往会借助随机数来实现目标,但实际情况下,计算机只能给我们提供伪随机数。
所谓伪随机数,“是按照一定算法模拟产生的,其结果是确定的,是可见的”。计算机产生随机数的过程,是根据一个种子为基准,以某个递推公式推算出来的一系列数,当递推的范围足够大、往复性足够强、又符合正态分布或平均分布时,我们就可以认为这是一个近似的真随机数。
c语言中,头文件stdlib.h(c++中是cstdlib)为我们提供了rand函数来生成随机数和srand()来提供随机数种子。
所谓种子可以看作随机数序列的名字,一个种子对应一串随机数序列,当种子不变时,就会按照随机数序列依次输出随机数。
1.默认种子
#include
#include
using namespace std;
#define max 1
#define min 10
int main()
{
int i;
for(i=0;i<10;i++){
cout<//生成随机数
}
return 0;
}
结果:
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
这个代码没有指定种子,所以第一次请求时,种子被设置为1,这个我们等一下可以看到
2.为种子赋值
2.1 循环内定种子
void Rand21(){
int i;
for(i=0;i<10;i++){
srand(1);
cout<<rand()<
41
41
41
41
41
41
41
41
41
41
这次的输出结果是是个41,因为我们在每一次输出随机数之前都为种子赋值,我们也可以知道,如果种子是默认值1,那么随机数序列的第一个值是41
2.2 循环外定种子
void Rand22(){
int i;
srand(1);
for(i=0;i<10;i++){
cout<<rand()<
输出结果和第一类一致,原因是默认的种子就是1,因此如果我需要产生更类似于真随机的随机数,我们就需要让种子也变得“随机”
2.3 循环外不定种子
void Rand231(){
int i;
srand(time(NULL));
for(i=0;i<10;i++){
cout<<rand()<
输出结果请大家自己测试,如果测试的频率很高的话,会发现各次数据的情况非常类似,数值之间的间隔也小,这就是由于时间相近导致的种子之间的差异小,随机数序列的差异也小
因此我们套用两次进行运算。
void Rand232(){
int i,j;
srand(time(NULL));
j=rand()+rand();
srand(j);
for(i=0;i<10;i++){
cout<<rand()<
每次测试的结果之间的差距就大了很多,多次使用的随机样本更趋近于“真随机”。
3.常见的取随机值的方法
3.1 在1~n之间取随机数
void Rand31(){
int i,n;
cin>>n;
for(i=0;i<10;i++){
cout<<1+(int)(n*rand()/RAND_MAX<//本样例用默认种子
原理是rand()函数的取值范围是1~32767,所以对随机生成的数值对应比例缩小或放大,即可实现
3.2 random(int)函数
random(int)函数和rand(void)函数的区别显而易见,random(int)函数输出的是指定范围内的随机数,而相同点是也可以用randomSeed()来制定种子
但需要注意的是,random函数不是标准库函数,vc、g++等编译器是不能识别的
3.3通用随机数公式
3.3.1 a~b之间的随机数
前文所使用的公式
a+(int)(b-a)*rand()/(RAND_MAX+1)//左闭右开
a+(int)(b-a)*rand()/RAND_MAX//闭合区间
对这个公式进行改良得到
rand()%(b-a)+a//开闭区间为左闭右开
rand()%(b-a)+a+1//开闭区间为左闭右开
rand()%(b-a+1)+a//开闭区间为闭区间
再由上面我们可以得到a~a+n的通用公式
a+rand()%n//这个函数的区间问题请大家参考上面来思考
3.3.2 0~1的小数
rand()/(double)RAND_MAX
由此推得a~a+1之间的小数
rand()/(double)RAND_MAX+a
在向外发展,结合3.3.1,a~b之间的小数
rand()/(double)RAND_MAX+rand()%(b-a)+a
以下要点需要在编写随机数程序过程中牢记
1.rand函数的生成结果由种子决定,种子默认为1
2.种子如果一定,那么随机的结果就会在完成一次循环后重复这一过程
3.即使不断的选取种子,所产生的数值都是伪随机,计算机无法实现真正的“真随机”
最后希望大家以后搞小活动的时候,如果需要随机数生成器,能自己编写一次属于自己的生成器,加个善意的小后门来做个小惊喜。