【C++11】随机值获取——random

我们知道,C 中的随机数函数只有一个 rand( ) ,想生成某一区间范围内的随机数乃至随机的浮点数都十分麻烦。

而 C++11 中提供的 random 库解决了这一问题,它能让我们方便地生成需要的随机值。

下面将介绍如何利用 random 库中的组件生成符合条件的随机数。

random 库中的组件分为两类——随机数引擎类和随机数分布类。

随机数引擎类是可以独立运行的随机数发生器,它以均匀的概率生成某一类型的随机数,但无法指定随机数的范围、概率等信息。因此,它也被称为“原始随机数发生器”,由于不能指定生成随机数的范围,它通常不会被单独使用。

随机数分布类是一个需要于随机数引擎类的支持才能运行的类,但是它能根据用户的需求利用随机数引擎生成符合条件的随机数,例如某一区间、某一分布概率的随机数。

所有随机数引擎类都支持的操作如下:

名称 功能
Engine e 创建一个引擎。
Engine e(s) 创建一个引擎,并用 s 作为种子。
e.seed(s) 使用种子 s 充值 e 的状态。
e.min( ), e.max( ) e 能生成的最小值和最大值。
e.discard(u) 将 e 推进 u 步(u 的类型为 unsigned long long)。

下表随机数分布类共有的操作:

名称 功能
U u 创建一个分布类 u 。
u(e) 用随机数引擎 e 生成随机数(u 代表随机数分布类)。
u.min( ) u 能生成的最小值。
u.max( ) u 能生成的最大值。
u.reset( ) 重置 u 的状态,使随后 u 生成的值不受之前的值影响 。

随机非负数——default_random_engine


default_random_engine 是一个随机数引擎类。它定义的调用运算符返回一个随机的 unsigned 类型的值。

因此,若想生成 10 个随机非负数并输出,程序可以这么写:

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

int main( ){
    default_random_engine e;
    for(int i=0; i<10; ++i)
        cout<<e( )<<endl;
    return 0;
}

在我们的系统中,测试结果为:

16807
282475249
1622650073
984943658
1144108930
470211272
101027544
1457850878
1458777923
2007237709

可以看出,还是比较“随机”的。

当然,default_random_engine 也只是一个伪随机数发生器,如果在运行一次程序,得到结果将还是这几个数。

若想令每次运行程序时的生成结果不同,可以为其设置较为随机的种子,比如当前系统的时间。

特定范围的非负数——uniform_int_distribution


uniform_int_distribution 是一个随机数分布类,也是个模板类,模板参数为生成随机数的类型(不过只能是 int、unsigned、short、unsigned short、long、unsigned long、long long、unsigned long long 中的一种)。它的构造函数接受两个值,表示随机数的分布范围(闭区间)。

因此,一个生成 0 到 9 的随机数程序可以这么写:

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

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

在我们的系统中,它的生成结果为:

0     
1     
7     
4     
5     
2     
0     
6     
6     
9     

随机浮点数——uniform_real_distribution


uniform_real_distribution 是一个随机数分布类,它也是模板类,参数表示随机数类型(可选类型为 float、double、long double)。构造函数也需要最大值和最小值作为参数。

下面是一个生成 10 个 0~1 之间的随机浮点数的例子:

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

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

在我们的系统上的结果为:

0.131538
0.45865
0.218959
0.678865
0.934693
0.519416
0.0345721
0.5297
0.00769819
0.0668422

随机布尔值——bernoulli_distribution


bernoulli_distribution 是一个分布类,但它不是模板类。它的构造函数只有一个参数,表示该类返回 true 的概率,该参数默认为 0.5 ,即返回 true 和 false 的概率相等。

下面是一个生成 10 个随机布尔值的例子:

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

int main( ){
    default_random_engine e;
    bernoulli_distribution u;
    for(int i=0; i<10; ++i)
        cout<<u(e)<<endl;
    return 0;
}

在我们的系统上的结果为:

1
1
1
0
0
0
1
0
1
1

总结


常用的随机数类如下:

  • default_random_engine:随机非负数(不建议单独使用)。
  • uniform_int_distribution:指定范围的随机非负数。
  • uniform_real_distribution:指定范围的随机实数。
  • bernoulli_distribution:指定概率的随机布尔值。

事实上,random 库的功能极其丰富,其中的随机数引擎不止有 default_random_engine 一个,分布类也远远不止上述三个。它还能进行泊松分布、正态分布、抽样分等高级的随机数功能,想详细了解这些内容请去查阅其他资料。我可能要等好久才能把这些内容补上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • 方法1 (数据类型)(最小值+Math.random()*(最大值-最小值+1)) 例: (int)(1+Math...
    GB_speak阅读 40,959评论 2 6
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,865评论 6 13
  • 本文根据众多互联网博客内容整理后形成,引用内容的版权归原始作者所有,仅限于学习研究使用,不得用于任何商业用途。 随...
    深红的眼眸阅读 2,200评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • 1.选中项目工程 -> PROJECT ->Localizations 点击下面的+号选择支持的语言包 2.com...
    AlexCorleone阅读 197评论 0 0