随机数的作用我就不说了,但凡要用随机数的童鞋一定是有这个需求。下面我们就分三个层次来介绍随机数生成。
文章目录
- 一、利用rand函数生成随机数
- 1、rand裸奔
- 2、随机数种子srand-随机数生成器
- 3、如何得到不同的种子值
- (1)、利用系统时间戳time()函数
- (2)、通过循环自己传入种子值
- (3)、多次随机作为种子值
- 二、利用rand类来生成随机数
- 1、介绍random类的使用
- 2、做一个随机生成姓名和成绩但的实例
文章随时可能更新,请关注文章原出处:https://blog.csdn.net/haigear/article/details/136032962
一、利用rand函数生成随机数
rand函数是c++自带的函数,它的有点是不需要另外包涵其他的类就可以直接使用。但第一次使用它的同学可能会感到失望。
1、rand裸奔
第一次使用rand失望的同学一定是一上来就用一个rand来裸奔,这样每次运行的结果都一模一样,根本达不到随机的目的,如下面的程序:
#include <iostream>
using namespace std;
int main() {
cout<< rand();
return 0;
}
上面的程序得到的随机数都是一样,是因为我们没有设置一个变化的随机种子random seeds。
2、随机数种子srand-随机数生成器
是不是我们设置了随机种子就可以呢?看看下面的代码:
#include <iostream>
using namespace std;
int main() {
srand(1000); ///
cout<< rand();
return 0;
}
实际上,我们得到的结果还是一样,每次的随机数都一样。为什么呢?
srand()函数的作用是用以设置随机数生成器的种子。随机数生成器通常基于一个算法,根据一个种子值来生成伪随机数序列。如果不设置种子值,每次程序运行时生成的随机数序列都是相同的。
通过调用srand()函数并传入一个种子值,可以改变随机数生成器的种子,从而使得每次程序运行时生成的随机数序列都不同。通常情况下,可以使用当前时间作为种子值,以确保每次生成的随机数序列都是不同的。
3、如何得到不同的种子值
一般来说有几种办法,一种是利用系统时间戳作为种子值,或者自己在循环中传入不同的种子值,下面我们看看这两种典型的随机数生成代码:
(1)、利用系统时间戳time()函数
srand(time(0));
for(int i=0;i<=100;i++){
//TODO
// srand(100000*i);
cout<< rand()%20<<endl; //20以内的随机数
}
(2)、通过循环自己传入种子值
for(int i=0;i<=100;i++){
//TODO
srand(100000*i);
cout<< rand()%20<<endl;//20以内的随机数
}
(3)、多次随机作为种子值
srand(time(0));
int frd;
for(int i=0;i<=10;i++){
//TODO
frd= rand()%19999;
cout<<frd<<":";
srand(frd);
cout<<rand()%60<<endl;
}
输出结果:
除此之外,我们如果有条件可以使用外界传感器获取的数据作为种子值。如果熟悉系统或者网络编程的,也可以利用网络瞬时的收发包数量或者CPU、gpu的利用率、硬盘的读写数据量作为种子,只是稍显麻烦。
二、利用rand类来生成随机数
1、介绍random类的使用
其实c++的类库中自带了一个rand的类,使用它,我们会更方便避免随机种子值的设置不当导致的每次取得的随机数都一样的问题。我们来看看代码:
#include <random>
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
int min=0;
int max=100;
random_device rd;
ranlux24 gen(rd());
uniform_int_distribution<> u(min, max);
for(int i=0;i<=20;i++){
cout<<u(gen)<<endl;
}
return 0;
}
我们这里就可以得到20个0到100内的随机数
我们可以看到,这里很容控制指定范围内的随机数,当然,我们也使用了好几个我们不得了解的几个random类中的几个对象:
random_device:是使用硬件熵源的非确定随机数生成器对象
uniform_int_distribution:随机分布对象,类似的还有伯松分布,正态分布,柯西分布,科舍尔分布等,这个可以根据自己的需要选择,要参看官方文档。
ranlux24:是一种预定义生成器
具体要了解random类中的这些对象我们可以参考这里点击进入
文章随时可能更新,请关注文章原出处:https://blog.csdn.net/haigear/article/details/136032962
可以这么说,用好了这个类,我们想要的真随机数就可以实现。
2、做一个随机生成姓名和成绩但的实例
首先我们来生成一个随机姓名,当然,每一次运行得到的姓名是不同的,代码如下:
#include <iostream>
#include <vector>
#include <random>
using namespace std;
int main() {
vector<string> surnames = {"史", "廖", "胡", "邢", "赵"};
vector<string> names = {"丽", "耀金", "德远", "珍香", "德恒"};
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> surname_dist(0, surnames.size() - 1);
uniform_int_distribution<> name_dist(0, names.size() - 1);
string surname = surnames[surname_dist(gen)];
string name = names[name_dist(gen)];
cout << "Random name: " << surname << name << endl;
return 0;
}
基于上面的方法,我们可以增加随机生成50个姓名及其成绩但的案例,以供我们的数据库学习的测试数据:
#include <iostream>
#include <vector>
#include <random>
using namespace std;
int main() {
const int num_students = 50;
const int num_subjects = 5;
vector<string> surnames = {"史", "廖", "胡", "邢", "赵","刘","钱","秦","朱","马","罗","瞿","余","郝","邵"};
vector<string> names = {"丽", "耀金", "德远", "珍香", "德恒","海洋","依琪","尚殊","阳","雨","梓辰","柯","骥","宇衡","清清","勇","玫玲","雨欣","思琪","可欣","雨柔","新宇","明鑫","鸣志","顾昀","扬名","世平","志伟"};
vector<vector<int>> grades(num_students, vector<int>(num_subjects));
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> grade_dist(0, 100);
uniform_int_distribution<> surname_dist(0, surnames.size() - 1);
uniform_int_distribution<> name_dist(0, names.size() - 1);
// 随机生成50个同学的姓名和5个学科成绩
// 输出成绩总表
cout << "Grades table:" << endl;
for (int i = 0; i < num_students; i++) {
string surname = surnames[surname_dist(gen)];
string name = names[name_dist(gen)];
cout <<surname << name << ":";
//cout << "Student " << i+1 << ": ";
for (int j = 0; j < num_subjects; j++) {
grades[i][j] = grade_dist(gen);
cout << grades[i][j] << " ";
}
cout << endl;
}
return 0;
}
输出的成绩单效果如下,当然,你也可以用filestream对象写入文件,这个很简单,你自己动手完善吧:
文章随时可能更新,请关注文章原出处:https://blog.csdn.net/haigear/article/details/136032962