您的位置:首页 > 其它

随机数常见问题及解决方案

2016-01-12 17:20 302 查看
本人最近在做项目,用到了随机数生成器,遇到一些问题,做一下记录,如果有朋友遇到这样的问题,也可以参考解决之。

- - - - - - - - - - - - - - - - - - - - - - - - - - – - - - - - - - - – - - - -

1、运行多次,为什么每次生成的随机数都是同样的数字?如何生成不同数字?

2、如何随机生成指定范围内的数字?如何生成指定精度的随机数?

3、如何随机生成若干不同的数字,并将其存在数组中?

- - - - - - - - - - - - - - - - - - - - - - - - - - – - - - - - - - - – - - - -

随机数所涉及的头文件为stdlib.h和time.h,所涉及的函数为srand(),rand(),time(),现在通过实验代码解决以上问题。

步骤:使用srand(unsigned seed)函数设置随机数种子,然后使用rand()函数获取随机数。

1、运行多次,为什么每次生成的随机数都是同样的数字?如何生成不同数字?

看代码:


#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main(){
int i,temp;
for(i=0; i<10; i++){
srand((unsigned)time(NULL)); //设置随机数种子

temp = rand()%100; //生成100以内的随机数
cout << temp<<" ";
}
cout<<endl;
return 0;
}


多次运行结果如下:

C:\Users…\Desktop>g++ ranom.cpp

C:\Users…\Desktop>a.exe

58 58 58 58 58 58 58 58 58 58

C:\Users…\Desktop>a.exe

84 84 84 84 84 84 84 84 84 84

C:\Users…\Desktop>a.exe

88 88 88 88 88 88 88 88 88 88

可以看到,每次运行的结果产生的随机数字都一样,这是因为虽然用srand函数设置了随机数种子,但是srand在for循环内部,由于for循环的运行速度很快,随机种子没有更换,也即种子相同,产生的随机数就相同。如果使用for循环产生不同的随机数就要把srand放到for循环之外,看如下代码:

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main(){
int i,temp;

srand((unsigned)time(NULL)); //设置随机数种子

for(i=0; i<10; i++){
temp = rand()%100; //生成100以内的随机数
cout << temp<<" ";
}
cout<<endl;
return 0;
}


结果如下:

C:\Users…\Desktop>g++ ranom.cpp

C:\Users…\Desktop>a.exe

83 38 61 40 32 31 42 51 92 51

C:\Users…\Desktop>a.exe

89 67 21 31 93 84 66 96 47 55

C:\Users…\Desktop>a.exe

96 64 82 90 23 69 91 42 2 58

可以看到在每次运行结果内,数字基本不相同。关键点就是要把srand放到for循环外面设置随机数种子。

2、如何随机生成指定范围内的数字?如何生成指定精度的随机数?

假如问题要求生成1-10,2-55,99-998等范围内的随机数,我们如何来求解。由问题1,及rand函数的解释可知,rand()%100生成的是0-100,内的随机数不包括100,简记为[0,100),根据这样一个分析我们可以生成任意范围内的随机数:

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main(){
int i,temp;
int low = 1;
int high = 10;

srand((unsigned)time(NULL)); //设置随机数种子

for(i=0; i<10; i++){
//rand()%(high-low)的范围是[0,high-low-1],加low,即为[low,high-1]≈[low,high)
temp = rand()%(high-low)+low;
cout << temp << " ";
}

cout<<endl;
return 0;
}


结果:

C:\Users***\Desktop>g++ ranom.cpp

C:\Users***\Desktop>a.exe

6 5 4 3 8 1 4 2 2 7

C:\Users***\Desktop>a.exe

4 1 3 2 3 7 5 8 5 9

C:\Users***\Desktop>a.exe

7 3 2 1 4 1 3 5 2 8

以上是生成[low,high)范围内的随机数。

有时候我们需要随机生成小数,并保证指定精度,比如2位小数、3位小数等,如何设置呢?

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main(){
int i;
double temp;

srand((unsigned)time(NULL)); //设置随机数种子

for(i=0; i<10; i++){
temp = rand()%100 * 0.01;  //随机生成两位小数
cout << temp << " ";
}

cout<<endl;
return 0;
}


C:\Users***\Desktop>g++ ranom.cpp

C:\Users***\Desktop>a.exe

0.16 0.93 0.53 0.58 0.49 0.89 0.96 0.81 0.48 0.29

C:\Users***\Desktop>a.exe

0.26 0.7 0.09 0.12 0.24 0.01 0.33 0.67 0.47 0.53

C:\Users***\Desktop>a.exe

0.29 0.51 0.05 0.07 0.39 0.28 0.46 0.4 0.58 0.05

如果要生成3位小数,只需要将100改为10^3,0.01改为0.1^3:

temp = rand()%1000 * 0.001;  //随机生成三位小数


3、如何随机生成若干不同的数字,并将其存在数组中?

rand生成的随机数是伪随机数,就是说有一定周期,生成若干个数字以后总会出现重复,但是一般情况下周期比较大,生成的数字足够使用。如何保证生成的数字都不相同呢?比如要生成5个8以内的随机数,见如下代码:

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string.h>

using namespace std;

int main(){
int i,j,len = 5,index,stop;
int temp,flag = 0,max = 8;
int *arr = new int[len];
memset(arr,-1,sizeof(int)*len);

srand((unsigned)time(NULL)); //设置随机数种子

index = 0; stop = 1;
cout<<"All Num: ";
while(stop){
temp = rand()%max; //生成随机数
cout<<temp << " ";
flag = 0;
for(j=0;j<index;j++)
{
if(arr[j] == temp){
flag = 1;
}
}
if(flag == 0)
{
arr[index ++] = temp;
if(index == len )
stop = 0;
}
}

cout << endl << "Selected:";
for(i=0; i<len; i++)
cout<<arr[i]<<" ";

return 0;
}


结果:

C:\Users***\Desktop>a.exe

All Num: 4 6 1 7 5

Selected:4 6 1 7 5

C:\Users***\Desktop>a.exe

All Num: 3 7 2 5 2 4

Selected:3 7 2 5 4

C:\Users***\Desktop>a.exe

All Num: 1 0 2 4 7

Selected:1 0 2 4 7

结果中,第一行是生成的所有随机数,第二行是所选取的随机数。

对于随机数的使用,一定要注意随机种子的设定,同时还要自己动手测试,总结规律掌握技巧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: