groovy: 也来玩玩梅森数
在javaeye的ruby版,看见ruby算梅森数组的一个贴,
很有趣啊。
我这里弄一个groovy的实现。
什么是梅森数组:
http://zh.wikipedia.org/w/index.php?title=%E6%A2%85%E6%A3%AE%E7%B4%A0%E6%95%B0&variant=zh-cn
给一个原始的实现:
boolean isPrime(n) { if(n==1) return false; if(n==2) return true; for(i in 2..Math.round(n**(0.5))){println i;if(n%i==0) return false} return true; } mersennes = []; (2..31).each{n=2**(it)-1;if(isPrime(n)) mersennes << n} println mersennes;
我的机器耗时2秒算到n=31的梅森数2147483647
,达到欧拉的水平.O^O
之后就很难了,等了5分钟也没算出下一个梅森数。
继续优化:
算法分析:
f(n)=2**n-1
f(n+1)=2**(n+1)-1=(2**n)*2-1=(2**n)*2-2+1=2(2**n-1)+1=2f(n)+1
==>
f(n+1)=2f(n)+1
eg:
f(1)=2**1-1=1
f(2)=2*f(1)+1=3
f(3)=2f(2)+1=7
f(4)=2f(3)+1=15
...
于是,代码如下,注意:加入了一个cache, 存放已经运算出来的f(n):boolean isPrime(n) { if(n==1) return false; if(n==2) return true; for(i in 2..Math.round(n**(0.5))){if(n%i==0) return false} return true; } cache = new HashMap(); def function(n) { if(cache.getAt(n)!=null) return cache.getAt(n) value = (n==1?1:2*function(n-1)+1) cache.putAt(n, value); return value; } (2..31).each{v=function(it);if(isPrime(v)) println "f"+it+"="+v}
还是算到f31,用时200毫秒,速度提高了一个数量级。
f61还是出不来。
大数据在groovy中默认为double的,估计要换成BigDecimal试一下。
相关推荐
软件的信雅达 2020-11-02
糖葫芦娃哈哈 2020-11-02
淡茶 2020-05-10
PHP学习笔记 2020-03-06
anvien 2020-01-08
quzhongwei 2020-01-06
淡茶 2020-01-03
tysforwork 2019-12-12
简单点好 2013-09-04
PeterHao0 2013-08-31
软件的信雅达 2019-11-19
软件的信雅达 2017-02-11
yiyilanmei 2015-04-28
无聊找点事做 2019-09-06
HaleyJenkins 2016-10-18
PeterHao0 2016-01-22
dieefer 2017-02-11
liushidexing 2016-11-03
春天花会开 2016-11-01