Daily Archives: July 1, 2016

一个生成伪随机数的超级算法【转】

转自:http://www.chncla.com/yk/201006/p_7.html 最近浏览“程序员论坛”时发现不少好帖,增长了不少知识,现拿其中一则为例与大家共同分享心得。 某人提出一个问题:怎样才能生成一亿个不重复的随机数? 问题表述起来很简单,似乎只要弄明白什么叫随机数以及怎样用电脑生成随机数,就能解决问题。 随机数,个人理解为一定范围内出现的毫无规律的数,比如扔一个骰子,落在桌面上时朝上的一面所表示的数就是随机数,这个数只能在1到6的范围内,但具体是什么数,谁也不能肯定,因为它没有规律。一组不重复的随机数,对扔骰子来说就是扔出六个不一样的数来,再比如洗一次扑克牌,洗完后就是54张不重复的随机数。 第二个问题,怎么样用电脑生成随机数?只要调用某个语言的某个函数即可。其实电脑是没办法生成真正的随机数,因为电脑是高度有规律的机器,让它生成一个没规律的数,根本办不到。平时程序员用某个函数生成的随机数,只是利用某个算法弄出来的伪随机数,看起来像,其实不是,能解决问题就行。 回到这个帖子所描述的问题上来。生成一亿个不重复的随机数,最直接的算法就是每用函数生成一个数,就把它放在一个筐里,第一个数直接放到筐里,以后生成的数在放到筐里之前和筐里的每一个数比较一番,一旦发现筐里有和新生成的数一样的数时,丢掉这个新生成的数,再接着生成数。 毫无疑问,这种算法的效率非常低,看看其中的比较次数就知道了,最差的次数趋于无穷次。也就是说到后来,几乎生成不了和以往不同的数。 当然还可以将这个算法升级为效率高得多的算法,每生成一个数,把这个数从随机数生成器取的范围中去掉,比如要生成10个随机数,第一次生成一个3,我把3从随机数的范围中去掉,第二次只从1到9这个范围内找。3对应4,4对应5……9对应10。这样就不存在比较的环节,然而又多出一个对应的环节,每生成一个数之后就要把剩下的数重新对应一遍,效率也不容乐观。 目前以我为代表的普通程序员的想象力也就到此为止,想不出什么高级解决办法,就当扔一块砖头出来,下面就把真正的碧玉——数学家级程序员的算法隆重介绍请出来。 我们先用另一种眼光来看不重复的随机数:加密。把一个能看懂的英文字符串打乱字母的顺序,变成不可读,这就是加密。但必须得有规律地打乱,字母a对应另外一个固定的字母Ax,字母b对应另外一个固定的字母Bx,以此类推,而且必须一一对应的。那么字符串“ab…z”这26个字母对应的26个加密字母“AxBx和Zx”就可以看成是对应范围a到z的不重复的伪随机数,这就是数学家的算法的来源。 看看回帖者的原文:   “可以采用32bit... Read More | Share it now!

BigDecimal 精确运算

其实java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。 在使用BigDecimal类来进行计算的时候,主要分为以下步骤: 1、用float或者double变量构建BigDecimal对象。 2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。 3、把BigDecimal对象转换成float,double,int等类型。 一般来说,可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。 ... Read More | Share it now!