C++中实现随机数(超详细!)

C++中实现随机数(超详细!​​​​​)

一、随机数函数:

rand()函数

在C++中可以用rand() 函数来产生一个0~RAND_MAX 之间的*"伪随机数"*。

需要导入一个库:

  include<cstdlib>

1.什么是RAND_MAX:

  它一般是个定值,且大小不可修改,它的大小取决于你的编译器和操作系统,如Linux最大可到2147483647而Windows可能只有32767这么小。

  可以用如下语句查看:

  cout<<RAND_MAX<<endl;

2.为什么是"伪随机数"呢?

  原因是真正的"真随机数"在计算机中是不存在的,随机数算法也是数学公式写的(有兴趣可以看一下这个博客:随机数生成算法)

  所以这就会导致一个问题:

    当在同一个编译器中执行rand()语句时都会得到同一套随机数。

为了避免这种情况,可以使用srand()初始化随机数种子

srand()函数

需要先导入:include<ctime>

需要随机数的程序一般都需要在最开始执行一次 srand((unsigned)time(NULL)), (time(NULL)返回自UTC时间1970年1月1日0点以来的秒数),它的作用是初始化随机数种子,当这种种子不一样时就能产生不同的一套随机数。

要注意,srand()函数只需要在主函数调用一次,否则可能会生成同一套随机数。

二、算法实现:

1、生成0~n之间的随机数(1)(包括0和n):

可以用 rand()%(n+1) 来实现

复制代码
int randint(int n){
    return (rand()%(n+1))
}

但是这一方法有个漏洞,那就是如果当n大于RAND_MAX时,就不能得到期望的结果,在windows中尤为明显。

通过rand()%n获得区间0,n-1的随机数有很大局限性,要保证n小于RAND_MAX

2、生成0~n之间的随机数(2)(包括n和0):

为了解决上面的问题,可以先执行rand()后再除以RAND_MAX,获得0~1之间的随机实数(因为RAND_MAX永远大于rand()的返回值),然后扩大n倍后四舍五入,获得0\~n之间的均匀整数。(虽然在n很大时精度不好,但对于普通的应用已经足够了)

复制代码
long long randint_no_max(long long n){//产生0~n之间的随机数(包括n和0),n可大于RAND_MAX
    double base=((double)rand())/RAND_MAX;//产生0~1之间的随机实数;
    long long res=((double)n*base+0.5);//再把上面的实数扩大n倍并四舍五入
    return res;
}

另外,如果想要更高的精度,可以采取多次随机的方法。

可以通过rand()/RAND_MAX获得0,n间的随机实数后再乘n获得0\~n间的均匀整数

3、 生成n~m之间的随机数(包括n和m):

  解决的思路其实很简单,先生成0~m-n之间的随机数然后再加上n即可:

复制代码
int randint_range(int n,int m){//产生n~m间的随机数(包括m和n)
	double base=((double)rand())/RAND_MAX;
	int res=n+(base*(double)(m-n+1));
	return res;
}

最终总结一下:(a,b均小于等于RAND_MAX)

**  (a,b) = (rand()%(b-a+1))+a-1
  a,b) = (rand()%(b-a))+a   (a,b = (rand()%(b-a))+a+1
  a,b = (rand()%(b-a+1))+a**

三、程序实例:

复制代码
#include<iostream>
#include<cstdlib>
#include<ctime>
const int MAXN=214748364;

using namespace std;

int a[MAXN];

void fill_randint(int a[],int cnt){//插入cnt个随机数到数组a
	for(int i=1;i<=cnt;i++){
		a[i]=rand();
	}
}

int randint(int n){//产生0~n之间的随机数(包括n和0),注意n<=RAND_MAX才有意义
	return (rand()%(n+1));
}

long long randint_no_max(long long n){//产生0~n之间的随机数(包括n和0),n可大于RAND_MAX
    double base=((double)rand())/RAND_MAX;//产生0~1之间的随机实数;
    long long res=((double)n*base+0.5);//再把上面的实数扩大n倍并四舍五入
    return res;
}

int randint_range(int n,int m){//产生n~m间的随机数(包括m和n)
	double base=((double)rand())/RAND_MAX;
	int res=n+(base*(double)(m-n+1));
	return res;
}


int main(){
	//初始化随机数种子
	srand((unsigned)time(NULL));
	//每个编译器或系统可能有不同的RAND_MAX:
	cout<<"RAND_MAX: "<<RAND_MAX<<endl;
	
	fill_randint(a,100000);
	cout<<a[100]<<' '<<a[101]<<endl;
	
	cout<<"0~n(n<=RAND_MAX): "<<randint(10)<<endl;

	cout<<"0~n(n can be any integer): "<<randint_no_max(2147483647)<<endl;
	
	cout<<"n~m(include n and m): "<<randint_range(32767,100000)<<endl;
	
	return 0;
}
相关推荐
Tyler_TXZ8 分钟前
C++C语言之——树
c语言·c++·算法·
m0_5474866615 分钟前
《面向对象与Java程序设计》全套PPT课件2026
java·开发语言
旖旎夜光18 分钟前
LeetCode 30:串联所有单词的子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
星恒随风19 分钟前
C++ 红黑树封装(二):迭代器、const_iterator 与 operator[] 完整实现 mymap 和 myset
开发语言·c++·状态模式
白狐_79824 分钟前
408 数据结构|完全二叉树两道典型题:第 6 层叶结点数与叶结点总数
数据结构·算法
lucas_AI26 分钟前
喂张白纸也能吐出证件号?文档 MLLM 的"关系级泄露"被测出来了
人工智能·算法·掘金技术征文
jason成都28 分钟前
ignav-next|Java 层封装 GNSS/INS 组合导航框架,隔离 RTKLIB 与 INS 内核,双模块独立演进、最小侵入
java·开发语言
抓不住时间的沙28 分钟前
butterfly主题美化,打造属于自己的个性博客
java·开发语言·前端·javascript·node.js·github
手写码匠40 分钟前
华为云Flexus+DeepSeek征文|Dify 多 Agent 灰度发布实战:让每一次变更都“小步快跑、随时可回滚“
人工智能·深度学习·算法·aigc
MarkHD42 分钟前
Stable Diffusion入门第19-20天:保存与分享你的工作流——第一阶段收官,从“能用”到“可复用”
java·开发语言·stable diffusion