C++-随机数的产生
一、随机数
以前学C语言的时候感觉随机数没啥用的,现在想想是自己无知啦,在帮人做一个项目的时候发现随机数还是相当有用的,我们可以利用随机数来生成大量的测试数据。
有两种方法可以让你的程序每次运行结果不同:
1.让用户输入不同的数据(或者从文件中读取不同的数据);
2.对用户输入的相同数据采取不同的处理方式,使其运行结果不同。
大多数情况下,第一种方法是非常好的,用户总是希望他们程序的结果是可预测的。比如当编写一个文本编辑器或者网页浏览器时,你会希望程序在用户每次输入一段文本或网址时执行同样的操作,而不是由浏览器随机决定访问哪个页面,除非是使用StumbleUpon1。
1StumbleUpon是一个能让你“偶遇”有趣网页的网站:http://www.stumbleupon.com/。
但在某些情况,每次执行相同操作并不是一个好的处理方式。例如,很多电脑游戏依赖随机,俄罗斯方块便是一个典型的例子,如果每次游戏方块的下落顺序都相同,用户便会记住下落顺序,因为可以预测接下来会出现什么方块,所以得分会一次比一次高。最后游戏和背诵圆周率的千位小数没啥不同。为了让俄罗斯方块游戏更有意思,程序需要随机选择下一次方块的形状和朝向。
为了实现这个功能,计算机需要生成随机数。因为计算机会准确执行命令,当我们执行相同的操作时计算机总会返回同样的结果。这就很难生成真正的随机数。不过没有必要生成真的随机数。生成像随机数的数也能达到目的,这就是伪随机数。
要生成伪随机数,计算机需要一个种子,利用数学变换将种子转换成另一个值。新值再成为下一个种子。如果程序每次采用不同的种子,程序便永远不会生成相同的数据序列。这里使用的数学转换需要特别挑选,要让所有数字的生成概率相等但又不会有明显的计算模型。(例如,它不会只是每次对数字加1。)
C++提供了所有的功能。你无需关心数学转换,C++中有相关的函数实现。所有你要做的只是提供随机种子,使用当前时间作种子即可。让我们看一下细节:
1.1 随机数的产生
C++有两个函数,一个是设置随机种子,另一个是用种子产生随机数:
void srand (int seed);
srand函数将某个数字设置为种子。在程序开头处需要调用一次srand。使用srand的典型方法是把time函数的结果作为参数,time函数返回一个代表当前时间的数值。
time函数返回从1970年1月1日起到现在的秒数。这个规则源自于Unix操作系统,有时它称为Unix time。大多数情况下,时间存储在32位有符号整型中。
随着时间的增加,秒数会超过整型可表示的范围,最后将以负数结尾表示过去的时间。超过整型数的现象将发生在2038年,它引起了对“2038年问题”(Year2038 Problem)的讨论,使用Unix time的计算机程序将会把2038年当做1901年处理。详情请参考:
http://en.wikipedia.org/wiki/Year_2038_problem。
srand ( time ( NULL ) );
目前你不用了解NULL参数,先就照着这么写;
如果连续调用srand,程序会反复地更新随机数发生器种子,因为连续调用的时间序列非常相近,生成的随机数也会很相近。(使用srand必须包含cstdlib头文件,使用time函数必须包含ctime头文件。
#include <cstdlib>
#include <ctime>
int main ()
{
//在最开始处调用一次
srand( time( NULL ) );
}
参照下面原型调用rand函数来获取随机数。
int rand ();
注意rand函数没有任何参数,仅有一个返回值。让我们将返回值输出出来。
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
int main ()
{
//在最开始处调用一次
srand( time( NULL ) );
cout << rand() << '\n';
}
C++有一个返回除法余数的操作符(如4/3商为1,余数为1)——模数运算符。如果你没有注意到也不要紧,人们总是自动屏蔽数学函数。但模数非常有用。因为被4整除的余数的范围是0~3。如果用rand函数返回的随机数除以所需数字的范围长度(即范围内数的数量),便会获得0到最大范围之间的值(不包含最大值)。
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
int randRange (int low, int high)
{
//先获取随机数,再处理得到从0到所需数字范围长度的值,然后加上最小值
return rand() % ( high - low + ) + low;
}
int main ()
{
srand( time( NULL ) );
for ( int i = ; i < ; ++i )
{
cout << randRange( , ) << '\n';
}
}
这段程序有两点需要注意的地方。首先,我们必须对high-low加1,举例说明原因,设想目标范围是0到10,当中有11种可能出现的值。减法获得的是两个值之间的差值,比范围内值的数量少1,因此必须加1。其次,注意我们需要加上目标范围的最小值,设想如果想获取10到20之间的数,通过上面的方法只能获取0到10之间的随机数,再加10才能将范围设定到10到20之间。
参考文献:c++现代程序设计方法
小结:
-我们产生随机数不用自己去编写数学变换公式,直接调用两个随机函数
-time(NULL)返回当前距离1970年的秒数,将其作为参数传递给srand生成随机种子;
-rand()生成随机数,无形参,每调用一次返回值一个
C++-随机数的产生的更多相关文章
- .Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数
.Net中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成10个随机数: ; i < ; i++) { Rando ...
- DotNet生成随机数的一些方法
在项目开发中,一般都会使用到“随机数”,但是在DotNet中的随机数并非真正的随机数,可在一些情况下生成重复的数字,现在总结一下在项目中生成随机数的方法. 1.随机布尔值: /// <summa ...
- JavaScript 随机数
JavaScript内置函数random(seed)可以产生[0,1)之间的随机数,若想要生成其它范围的随机数该如何做呢? 生成任意范围的随机数 //生成[100,120)之间的随机数 Math.fl ...
- SQL Server 随机数,随机区间,随机抽取数据rand(),floor(),ceiling(),round(),newid()函数等
在查询分析器中执行:select rand(),可以看到结果会是类似于这样的随机小数:0.36361513486289558,像这样的小数在实际应用中用得不多,一般要取随机数都会取随机整数.那就看下面 ...
- 随机数(random)
需求 Random rd=new Random(); 需要十以内的随机数 (0---10) System.out.println((int)((rd.nextDouble()*100)/10)); ...
- [LeetCode] Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数
Design a data structure that supports all following operations in average O(1) time. insert(val): In ...
- Python 随机数用法
1. random.seed(int) 给随机数对象一个种子值,用于产生随机序列. 对于同一个种子值的输入,之后产生的随机数序列也一样. 通常是把时间秒数等变化值作为种子值,达到每次运行产生的随机系列 ...
- C语言产生标准正态分布或高斯分布随机数
C语言 产生标准正态分布或高斯分布 随机数 产生正态分布或高斯分布的三种方法: 1. 运用中心极限定理(大数定理) #include #include #define NSUM 25 double g ...
- C语言基础(11)-随机数发生器
一. rand() rand是一个C语言库函数,功能是生成一个随机数.rand需要一个不同的种子,才能生成不同的随机数. 二. srand(int seed) rand需要一个不同的种子,才能生成不同 ...
- shell 指定范围产生随机数
#/bin/bash echo "---------------产生随机数---------------" read -p "请输入起始数:" a read - ...
随机推荐
- 数据库->神奇的concat_ws函数
神奇的concat_ws函数 了解到concat_ws函数起因是因为:朋友给我发了一份面试题,其中有一句看似很简单的查询,但是我就是没做出来.如下图: 经查阅资料了解通过两个字段拼接并且用“_”进 ...
- [USACO19OPEN]Valleys P
题意 洛谷 做法 用并查集维护区域,剩下的就只用判是否有洞就好了 然后手玩出一个结论:凸角为\(+1\),凹角为\(-1\),和为\(sum\),洞数\(h\),满足\(sum=4-4h\) 位置\( ...
- Windows10开发环境搭建
开发环境基本介绍:(是以刚重装过系统的电脑进行介绍的,电脑刚装完的操作见其他的文档) Eclipse环境搭建: 1. 下载JDK (本例以JDK13.0.1为例) 2. 配置环境变量(主要是JAVA_ ...
- gulp常用插件之gulp-load-plugins使用
更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-load-plugins这是一款批量引入package.json文件中的依赖项工具. 更多使用文档请点击访问gulp-load-plug ...
- ROS开发--在订阅话题的回调函数中发布话题
处理激光数据时,需要将处理后的激光数据再发布,需要保持一致的频率,所以必须在回调函数中发布激光数据信息. 代码参考:https://blog.csdn.net/heyijia0327/article/ ...
- [POI2013] LAN-Colorful Chain - 桶
给定一个序列,求有多少个子串使得 \(c_i\) 这个数在这个序列中出现了 \(l_i\) 次,且不存在其它的数. Solution 滑动窗口搞一下 #include <bits/stdc++. ...
- HW - VCN 介绍
VCN 是个管理摄像机的平台 用来增删改查摄像机,获取摄像机视频流,获取录像 vcn会基于我们的接口做一次开发,作为相机的统一管理入口,获取相机的信息
- pandas玩转excel-> (1)如何利用pandas创建【行,列,单元格】
import pandas as pd #------新建单元格的方法一:通过先创建字典的形式 #可以先新建一个字典d={'x':100,'y':200,'z':300} #打印字典的索引print( ...
- 网络中的 TCP/IP
TCP/IP OSI的“实现”:TCP/IP OSI七层模型 TCP/IP概念层模型 功能 TCP/IP协议族 应用层 应用层 文件传输.电子邮件.文件服务.虚拟终端 FTP,HTTP,SMTP,SN ...
- ACM-ICPC 2018 徐州赛区网络预赛 Ryuji doesn't want to study
简单数学变换+线段树 简单数据结构签到题不解释 本来应该贴板子的,鉴于最近写代码太少了,而且由于要用两个线段树,平时板子都是一个的.以及板子在队友那.就当熟悉写代码,自己写了一下. #include ...