C/C++中设置随机数

前言

我们通常在写一个数据结构后,需要去测试其正确性和性能比较,那在平常手动输入数据的方式太鸡肋,并且不具有普遍性和随机性。基于这个原因,我们必须要掌握设置随机数,不但可以给我们提供更多的数据,还可以让数据具有普遍意义,满足我们的测试需求。

一、有关随机数的函数

1. srand

cpp 复制代码
void srand (unsigned int seed);

函数解析:

seed就相当于一颗种子,srand函数会种这个随机数种子,种子对应一个随机数,后面使用rand函数可以接收这个随机数。

经过测试:当我们的种子是固定的,每次程序运行时,rand获得的随机数也是固定的,无法做到在一个程序里获得真正意义的随机数,所以参数通常使用的是time(NULL),time函数是获得系统的时间,因为系统的时间一直在变,那种子就也都是不同的,所以每次程序运行时,rand获得的数,也一直在变,这才是真正意义的随机数。

为什么参数一定时,获得的随机数是固定的?

首先计算机并不能产生真正的随机数,而是将一些无规则排列的数字存储在电脑里,再把这些数字划分为相等的N份,并为每份加上一个编号。用srand()函数获取这个编号,然后rand()就按顺序获取这些数字。

头文件:

cpp 复制代码
#include <stdlib.h>

参数seed:

推荐使用time(NULL),用时间做参数,可以保证每次程序运行时,生成的随机数是随机的
time函数头文件:#include <time.h>

返回值:

无返回值

2. rand

cpp 复制代码
int rand (void);

头文件:

cpp 复制代码
#include <stdlib.h>

函数解析:

得到srand生成的随机数,并返回这个随机数

返回值:

返回的是随机数,范围0~RAND_MAX(RAND_MAX = 2147483647)

二、测试模版

cpp 复制代码
 int main()
{
	const size_t N = 10000;

	unordered_set<int> us;  //容器1
	set<int> s;             //容器2 

	vector<int> v;          //使用vector保存插入的数据
	v.reserve(N);           //防止多次扩容,造成消耗,提前一次预留N个空间
    
	srand(time(nullptr));   //种随机数种子,使用time做参数,可以保证每次运行,都是不一样的
    
	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(rand()); // N比较大时,重复值比较多
		//v.push_back(rand()+i); // 重复值相对少
		//v.push_back(i); // 没有重复,有序
	}

	//测试容器插入的性能
	size_t begin1 = clock();
	for (auto& e : v)
	{
		s.insert(e);
	}
	size_t end1 = clock();
	cout << "set insert:" << end1 - begin1 << endl;

	size_t begin2 = clock();
	for (auto& e : v)
	{
		us.insert(e);
	}
	size_t end2 = clock();
	cout << "unordered_set insert:" << end2 - begin2 << endl;

    //测试容器查找的性能
	size_t begin3 = clock();
	for (auto& e : v)
	{
		s.find(e);
	}
	size_t end3 = clock();
	cout << "set find:" << end3 - begin3 << endl;

	size_t begin4 = clock();
	for (auto& e : v)
	{
		us.find(e);
	}
	size_t end4 = clock();
	cout << "unordered_set find:" << end4 - begin4 << endl << endl;

	cout <<"插入数据个数:"<< s.size() << endl;
	cout <<"插入数据个数:" << us.size() << endl << endl;

    //测试容器删除的性能
	size_t begin5 = clock();
	for (auto& e : v)
	{
		s.erase(e);
	}
	size_t end5 = clock();
	cout << "set erase:" << end5 - begin5 << endl;

	size_t begin6 = clock();
	for (auto e : v)
	{
		us.erase(e);
	}
	size_t end6 = clock();
	cout << "unordered_set erase:" << end6 - begin6 << endl << endl;

	return 0;
}

三、反思与总结

由于目前能力不足,还需要仔细研究源码中srand和rand的底层实现,在未来某段时间会更新剖析源码实现
random.c source code [glibc/stdlib/random.c] - Codebrowser

相关推荐
毕设源码-邱学长几秒前
【开题答辩全过程】以 基于Java Web的电子商务网站的用户行为分析与个性化推荐系统为例,包含答辩的问题和答案
java·开发语言
程序员清洒6 分钟前
Flutter for OpenHarmony:Text — 文本显示与样式控制
开发语言·javascript·flutter
摇滚侠16 分钟前
Java项目教程《尚庭公寓》java项目从开发到部署,技术储备,MybatisPlus、MybatisX
java·开发语言
轩情吖27 分钟前
Qt的窗口
开发语言·c++·qt·窗口·工具栏·桌面级开发
€81128 分钟前
Java入门级教程24——Vert.x的学习
java·开发语言·学习·thymeleaf·数据库操作·vert.x的路由处理机制·datadex实战
L1869245478237 分钟前
无外设条件下的自动找眼V2
c++
hcnaisd238 分钟前
深入理解C++内存模型
开发语言·c++·算法
凯子坚持 c41 分钟前
Qt常用控件指南(8)
开发语言·数据库·qt
李老师讲编程1 小时前
C++信息学奥赛练习题-杨辉三角
数据结构·c++·算法·青少年编程·信息学奥赛
冠希陈、1 小时前
PHP 判断是否是移动端,更新鸿蒙系统
android·开发语言·php