一、随机数

  以前学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()生成随机数,无形参,每调用一次返回值一个

最新文章

  1. &lt;&lt;&lt; 网页中如何利用原生js和jquery储存cookie
  2. DllImport dll中有些啥函数 及 dll中是否用到了别的dll
  3. &amp;1的用法
  4. Block深入浅出
  5. C# 工厂模式示例
  6. owncloud乱码问题
  7. HDU 4292Food(网络流的最大流量)
  8. 手机号码抽奖系统(JS)
  9. 【Spring】web开发 javaConfig方式 图解
  10. Spring MVC体系结构和处理请求控制器
  11. CODING 如何使用 CODING 研发管理系统来敏捷开发
  12. python3: 自动化测试框架pytest
  13. R语言预测实战(游浩麟)笔记2
  14. JAVA主流日志梳理
  15. CodeForces 433C Ryouko&#39;s Memory Note (中位数定理)
  16. dll 恐怖的代码调整
  17. Alpha 冲刺 (5/10)
  18. React设置宽度的坑
  19. 304 Not Modified 简述
  20. 腾讯云CMQ消息队列在Windows环境下的使用

热门文章

  1. 将String类型的json数据转换为真正的json数据
  2. [Blog] Part1: 技术札记-写个创站小结吧
  3. NOI Online能力测试游记:退役选手的自娱自乐
  4. [CF1303D] Fill The Bag - 贪心
  5. vue中的this.$nextTick()使用
  6. AI机器人最高等级
  7. z3学习档案
  8. 用友UAP NC 单据新增数据时抛出&quot;流程平台缓存中不存在该单据或交易类型=HB06&quot;
  9. Python学习笔记三:数据特征分析
  10. jQuery---第一部分复习