C++产生随机数

一、前言

在看C++生成随机数之前,先来看一下如何C语言如何生成随机数

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

int main()
{
	int i = 0;
	// 初始化种子为随机值
	srand((unsigned int)time(0));
	for (; i < 5; ++i)
	{
		// 产生一个1-50之间的数
		int num = rand() % 50 + 1;
		printf("%d ", num);
	}
	printf("\n");
	return 0;
}

当我们想要生成随机浮点数时,通常需要rand() / MAX_RAND,但是随机整数的精度通常低于随机浮点数,有一些浮点数就永远不会生成了,一起来看一下C++是怎么做的。

二、随机数引擎操作

Engine e;默认构造函数,使用该引擎类默认的种子
Engine e(s);使用整型值 s 作为种子
s.send(s);使用整型值 s 重置种子的状态
e.min();引擎可生成的最小值
e.max();引擎可生成的最大值
Engine::result_type;此引擎生成 unsigned 整型类型
e.discard(u);将引擎推进 u 步,u 的类型为 unsigned long long

三、生成整型随机数

1. 生成无符号数,注意包含 #include <random>

#include <iostream>
#include <random>
#include <vector>
using namespace std;

int main()
{
	uniform_int_distribution<unsigned> u(0, 9);
	default_random_engine e;
	for (int i = 0; i < 5; i++)
	{
		for (auto i = 0; i < 10; i++)
			cout << u(e) << " ";
		cout << endl;
	}
	return 0;
}

2. 生成一个 0~9 的随机数

#include <iostream>
#include <random>
using namespace std;

int main()
{
	uniform_int_distribution<unsigned> u(0, 9);
	default_random_engine e;
	for (auto i = 0; i < 10; i++)
		cout << u(e) << " ";
	cout << endl;
	return 0;
}

3. 将引擎和关联的对象修改为 static 的 

#include <iostream>
#include <random>
using namespace std;

void Test()
{
	uniform_int_distribution<unsigned> u(0, 9);
	default_random_engine e;
	for (auto i = 0; i < 10; i++)
		cout << u(e) << " ";
	cout << endl;
}

int main()
{
	for (int i = 0; i < 5; i++)
	{
		Test();
	}
	return 0;
}

每次调用这个函数都将生成相同的随机数 

为了解决这个错误,我们可以将引擎和关联的对象修改为 static 的 

#include <iostream>
#include <random>
using namespace std;

void Test()
{
	uniform_int_distribution<unsigned> u(0, 9);
	default_random_engine e;
	for (auto i = 0; i < 10; i++)
		cout << u(e) << " ";
	cout << endl;
}

int main()
{
	for (int i = 0; i < 5; i++)
	{
		Test();
	}
	return 0;
}

 可以看到生成了不同的随机数

4. 随机数种子

使用上面的函数每次调用都将生成相同的随机数,类似 C 语言,C++ 也有随机数种子 

#include <iostream>
#include <random>
#include <time.h>
using namespace std;

int main()
{
	uniform_int_distribution<unsigned> u(0, 9);
	default_random_engine e;
	e.seed(time(0));
	cout << "e:";
	for (auto i = 0; i < 10; i++)
		cout << u(e) << " ";
	cout << endl;
	default_random_engine e1;
	e1.seed(2356);
	cout << "e1:";
	for (auto i = 0; i < 10; i++)
		cout << u(e1) << " ";
	cout << endl;
	e1.seed(2356);
	cout << "e2:";
	for (auto i = 0; i < 10; i++)
		cout << u(e1) << " ";
	cout << endl;
	return 0;
}

相同的随机数种子生成的随机数是一样的

四、浮点型随机数生成

生成 0~1 的随机浮点数

#include <iostream>
#include <random>
using namespace std;

int main()
{
	uniform_real_distribution<double> u(0, 1);
	default_random_engine e;
	for (auto i = 0; i < 10; i++)
		cout << u(e) << " ";
	cout << endl;
	return 0;
}

 默认为double,uniform_real_distribution<> u(0, 1) 相当于 uniform_real_distribution<double> u(0, 1);

0.814724 0.135477 0.905792 0.835009 0.126987 0.968868 0.913376 0.221034 0.632359 0.308167

五、非均匀随机数生成

1. 正态分布

#include <iostream>
#include <random>
#include <string>
#include <vector>
#include <time.h>
using namespace std;

int main()
{
	default_random_engine e;
	e.seed(time(0));
	// 均值 4,标准差 1.5
	normal_distribution<> n(4, 1.5);
	std::vector<unsigned> array(9);
	for (auto i = 0; i < 300; i++)
	{
		unsigned num = lround(n(e));
		if (num < array.size())
			++array[num];
	}
	for (auto i = 0; i != array.size(); i++)
		cout << i << ":" << string(array[i], '*') << endl;
	cout << endl;
	return 0;
}

2. 生成一个 bool 值 

#include <iostream>
#include <random>
#include <time.h>
using namespace std;

int main()
{
	default_random_engine e;
    e.seed(time(0));
	bernoulli_distribution b;
	for (auto i = 0; i < 20; i++)
	{
		cout << boolalpha <<  b(e) << " ";
	}
	cout << noboolalpha << endl;
	return 0;
}

cout << noboolalpha << true; 将bool 值打印为 true 或者 false,而不是 0 和 1,cout << noboolalpha << endl; 取消

false true false false true false false true false true true false true true false false false false false false

58/52 的机会为 true 

bernoulli_distribution b(.58);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值