本人最近在做项目,用到了随机数生成器,遇到一些问题,做一下记录,如果有朋友遇到这样的问题,也可以参考解决之。
- - - - - - - - - - - - - - - - - - - - - - - - - - – - - - - - - - - – - - - -
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改为103,0.01改为0.13:
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
结果中,第一行是生成的所有随机数,第二行是所选取的随机数。
对于随机数的使用,一定要注意随机种子的设定,同时还要自己动手测试,总结规律掌握技巧。