首先我们来说说C++中的随机数生成:

我们知道在C++用函数rand()获取的是一个0 ~ RAND_MAX之间的一个随机数。其中RAND_MAX的值为32767。

首先我们来分析两个程序:


#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>using namespace std;int main()
{srand(time(0));for(int i=0;i<10;i++){int t = rand();cout<<t<<endl;}return 0;
}
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>using namespace std;int main()
{for(int i=0;i<10;i++){srand(time(0));int t = rand();cout<<t<<endl;}return 0;
}

我们分别输出这两个程序的结果会发现,第一个程序结果为:

而第二个程序的结果是:

很明显,我们希望得到第一种结果。那么把srand(time(0))放到循环体内和放到循环体外有什么不同?

现在我来详细解释上面的结果。

我们首先要明确,对于函数srand(int num)和函数rand()它们是定义在头文件<stdlib.h>里的。

而srand(int num)函数的作用是散布num个随机数,当用rand()时,获取的是散布的这num个数中的任意一个。

rand()函数返回随机数序列中的下一个数,实际上srand(int num)函数是一个伪随机数序列,序列中的每一个数是由对其前面的数字进行复杂变换得到的。为了模仿真正的随机性,首先要调用srand()函数给序列设置一个种子。为了更好地满足随机性,使用了时间函数time(),以便取到一个随时间变化的值,使每次运行rand()函数时从srand()函数所得到的种子值不相同。伪随机数生成器将作为 "种子 "的数当作初始整数传给函数。这粒种子会使这个球(生成伪随机数)一直滚下去。

time(0)返回的是一个整数,这个整数的值等于1970年1月1日0时0分0秒至现在的秒数。所以这样随着时间的不同,生成的随机数的个数也不同。

至于第二个程序中所有的数字都相同,那是因为本身循环并不多,每个循环时间间隔很近,所以实际上time(0)的值都一样。这样相当于每次都是取随机序列中的第一个元素,那当然就一样了。

上面提到了生成的随机序列实际上是一个伪随机序列,其实后面的数是根据前面的数经过复杂的变换得到的。我们可以来看看srand(int num)函数的大体实现原理。

#include <iostream>
#include <string.h>
#include <time.h>
#include <stdio.h>#define RANDOM_MAX 0x7FFFFFFFusing namespace std;static long do_rand(unsigned long *value)
{/*这个算法保证所产生的值不会超过(2^31 - 1)这里(2^31 - 1)就是 0x7FFFFFFF。而 0x7FFFFFFF等于127773 * (7^5) + 2836,7^5 = 16807。整个算法是通过:t = (7^5 * t) mod (2^31 - 1)这个公式来计算随机值,并且把这次得到的值,作为下次计算的随机种子值。*/long quotient, remainder, t;quotient = *value / 127773L;remainder = *value % 127773L;t = 16807L * remainder - 2836L * quotient;if (t <= 0)t += 0x7FFFFFFFL;return ((*value = t) % ((unsigned long)RANDOM_MAX + 1));
}static unsigned long next = 1;int rand(void)
{return do_rand(&next);
}void srand(unsigned int seed)
{next = seed;
}int main()
{srand((unsigned)(time(NULL)));for(int i=0;i<100; i++){if(i % 10 == 0) puts("");printf("%d\t",rand()%99+1);}return 0;
}


经过上面的分析,就很容易获取一个0 ~ 1之间的一个随机小数。因为随机数中RAND_MAX最大,那么就很容易了:

double get_rand()
{return (double)rand() / (double)RAND_MAX;
}

在很多重要的算法中,我们没有用srand(int num)函数而直接用rand()来获取随机数,比如Miller素数测试,大数分解 等等。这时实际上有一个默认的随机种 子,这个随机序列是固定的。



那么,Java中的随机数又是怎么样的呢?

在java语言中生成随机数的方法有三种:

  1.通过System.currentTimeMillis()方法获取当前时间的毫秒数(long);

  2.通过Math.random()方法获取一个介于0到1之间的伪随机数;

  3.通过Random类获取随机数;

  在Random类中,使用了一个48位的种子数,并通过线性同于公式进行随机数的生成(参考《The Art of Computer Programming, Volume 2》书的3.2.1节。

  Random rand = new Random(System.currentTimeMillis());

在Java 中我们可以使用java.util.Random类来产生一个随机数发生器。它有两种形式的构造函数,分别是Random()和Random(long seed)。Random()使用当前时间即System.currentTimeMillis()作为发生器的种子,Random(long seed)使用指定的seed作为发生器的种子。

随机数发生器(Random)对象产生以后,

通过调用不同的method:nextInt(),nextLong(),nextFloat(),nextDouble()等获得不同类型随机数。

生成随机数
Random random = new Random();

Random random = new Random(100);//指定种子数100

random调用不同的方法,获得随机数。

import java.util.Random;public class Srand {public static void main(String[] args){Random random = new Random(100);System.out.println(random.nextInt());System.out.println(random.nextFloat());System.out.println(random.nextBoolean());}
}

注意Java的Math类中也有一个random()方法,即Math.random()返回的是一个范围为[0.0,1.0)之间的小数。

在Java中,下面的代码表示生成10个0到49之间的随机数。

import java.util.Random;public class Srand {public static void main(String[] args){Random random = new Random();for(int i=0;i<10;i++){System.out.println(random.nextInt(50));}}
}

在Python中,随机数的生成需要先导入random模块。

1.random.random()用于生成一个0到1的随机符小数: 0 <= n < 1.0

>>> import random
>>> random.random()
0.9658869832707923
>>> 

2.random.uniform的函数原型为:random.uniform(a, b),用于生成一个指定范围内的随机符点数,两个参数一 个是上限,一个是下限。如果a > b,则生成的随机数n: a <= n <= b。如果 a<b, 则 b <= n <= a。

>>> random.uniform(1,10)
8.241539762435707
>>> random.uniform(10,1)
5.2752945576846075>>> 

3.random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。其中参数a是下限, 参数b是上限,生成的随机数n: a <= n <= b

>>> random.randint(1,10)
8

4.random.randrange的函数原型为:random.randrange([start], stop[, step]),从指定范围内,按指定基数 递增的集合中 获取一个随机数。如:random.randrange(10, 100, 2),结果相当于从[10, 12, 14, 16, ...  96,  98]序列中获取一个随机数。random.randrange(10, 100, 2)在结果上与random.choice(range(10,  100,2) 等效。

>>> random.randrange(0,100,2)
20

5.random.choice从序列中获取一个随机元素。其函数原型为:random.choice(sequence)。参数sequence表示一个 有序类型。这里要说明 一下:sequence在python不是一种特定的类型,而是泛指一系列的类型。list, tuple, 字符 串都属于sequence。

>>> random.choice('ACdreamers')
'e'

6.random.shuffle的函数原型为:random.shuffle(x[, random]),用于将一个列表中的元素打乱。

>>>
p = ['ACdreamers','Hello','World','NiHao']>>> random.shuffle(p)>>> print p
['World', 'Hello', 'ACdreamers', 'NiHao']>>> 

7.random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。 如果k大于sequence元素个数的话会报错。

>>> random.sample('ACdreamers',2)
['s', 'a']>>> 


关于C++,Java和Python中的随机数生成法相关推荐

  1. 一篇搞懂Python中的随机数

    在 python 中生成随机样本的所有你需要的示例列表 长按关注<Python学研大本营>,加入读者群,分享更多精彩 扫码关注<Python学研大本营>,加入读者群,分享更多精 ...

  2. Java和Python中类似Kotlin的生成器,续:附加参数

    介绍 在今天的文章中,我们将继续上周的文章,内容涉及用Java和Python制作类似于Kotlin的构建器,扩展构建器API以采用一些可选参数来提高灵活性. 我们继续我们HTML示例,尝试添加标记属性 ...

  3. python中产生随机数模块_Python中random模块生成随机数详解

    Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

  4. [转载] Python中产生随机数

    参考链接: Python中生成安全的随机数 Python产生随机数: 一.Python自带的random库 1.参生n--m范围内的一个随机数:    random.randint(n,m) 2.产生 ...

  5. 正则表达式及其在Java和Python中的相关操作

    1.PCRE表达式全集1 字符 描述 \ 将下一个字符标记为一个特殊字符.或一个原义字符(有^$()*+?.[\{|共计12个)或一个向后引用或一个八进制转义符 ^ 匹配输入字符串的开始位置 $ 匹配 ...

  6. java和python中函数式编程

    本篇文章将基于java和python分别介绍Lambda表达式,包括定义,使用等 java函数式编程 自jdk1.8开始,java中引入了函数式编程,使编程更加简洁灵活.接下来通过详细的例子阐述 函数 ...

  7. C++、Java、python中的一些常见容器总结

    主要参考:<数据结构与算法/leetcode/lintcode题解>.C++参考手册.<疯狂Java> 文章目录 <数据结构与算法>学习笔记(一)基础知识-基本数据 ...

  8. Python中的随机数生成器模块(真/伪随机数)

    真随机数发生器(TRNG) 真随机数发生器会生成几乎无法预测的随机数,因为影响结果值变化的因素是物理环境的特征.例如,掷骰子将生成难以预测的随机值.但是骰子的数量限制为1到6.因此,几乎很难预测生成随 ...

  9. 【写给以前的自己】python中,既生list何生tuple?简论学习数据结构(e.g.哈希化)对自己的提升

    刚学python时,很奇怪:python中list可增减元素,调用遍历也都方便,有了list为什么要有一个tuple的原生数据类型呢?list有的特性(比如长度弹性)tuple没有,而tuple能干的 ...

最新文章

  1. Zabbix监控网络设备日志文件及字段报警
  2. 重绘(repaint)与渲染(reflow)
  3. centos 6.5 rpm mysql_Linux平台(CentOS 6.5) RPM包方式安装 Mysql 5.7
  4. python脚本根据cookies自动登录网站_python模拟登录并且保持cookie的方法详解
  5. Python成为TIOBE 2020年度编程语言!是获此奖项次数最多的语言
  6. Writing a good grant proposal
  7. VC6.0多线程例程
  8. python实现希尔排序(已编程实现)
  9. 0031-如何在CDH启用Kerberos的情况下安装及使用Sentry(一)
  10. 轻量级网络模型之MobileNet系列
  11. 在浏览器中输入url地址 - 显示主页的过程
  12. 禁止绿盟扫描oracle,Oracle Enterprise Manager Grid Control JSP代码执行漏洞(CVE-2010-3600)
  13. 关于intel六代/七代CPU安装win7系统解决USB3.0驱动的镜像文件
  14. 红米6pro刷机教无人直播包教程
  15. 有点理解Google为什么要退出中国市场了
  16. android 远程调试工具,Android 远程调试工具STF——开源项目
  17. Spell Checker
  18. 广东省取消职称英语和计算机,职称评审!这些省份短期内不会取消职称英语、计算机!...
  19. 串口服务器调试助手使用教程,如何配置串口服务器及串口调试的六个技巧
  20. 世界顶级企业的数据中台实践剖析

热门文章

  1. Spring框架版本命名规则
  2. 字符流中的编码解码问题
  3. 结合zuul网关的鉴权流程
  4. Nginx与Zuul之间区别
  5. 数据库-mysql基础操作之输入查询
  6. finally代码块
  7. Hystrix Dashboard的使用与常见问题总结
  8. Bootstrap组件_警告框
  9. 原型共享数据 原型简单语法 原型中方法是可以相互访问 实例对象属性方法层层搜索
  10. 小学数学加减法测试软件,小学生数学加减测试题