使用Java8优化Fibonacci数
2014-03-22 19:34
323 查看
Fibonacci数的定义如下:
在Java中,该算法的非常好容易实现
从上图可知,该算法存在严重的重复计算。
但是在Java8中,利用其两个新特性,可以优化该算法。
思路如下:
上面算法最严重的问题就是存在太多的重复计算,因此我们可以使用内存来尽量规避这个问题,也就是说,提供一种缓存结果的机制来规避重复计算。
在Java中,可以将Fibonacci数缓存在哈希表或者Map中,这样只需要最左边分支使用递归来计算,并将计算结果缓存到Map中,所有的右边分支只需到哈希表中查询,
在哈希表中找到中的正确结果返回即可,不需要再次计算。
在Java8给Map增加了一些新方法,简化了上面这个思路的实现,比如computeIfAbsent(key, function),该函数key可以为需要计算的数字,而function为一个能够递归计算Fibonacci数的lambda表达式,如果key对应的Fibonacci数不在map中,则该lambda表达式能够正确的计算出Fibonacci数
首先要定义一个Map,同时缓存fibonnaci(0) 和 fibonacci(1)的结果
在Java中,该算法的非常好容易实现
public static long fibonacci(int x) { if(x==0 || x==1) return x; return fibonacci(x-1) + fibonacci(x-2); }但是该算法存在严重的效率问题:对于每一个数字,该算法会递归调用自身两次,其中每次一个分支都会重新计算另一个分支的一部分,例如下面计算fibonacci(5)的计算细节的树形图如下:
从上图可知,该算法存在严重的重复计算。
但是在Java8中,利用其两个新特性,可以优化该算法。
思路如下:
上面算法最严重的问题就是存在太多的重复计算,因此我们可以使用内存来尽量规避这个问题,也就是说,提供一种缓存结果的机制来规避重复计算。
在Java中,可以将Fibonacci数缓存在哈希表或者Map中,这样只需要最左边分支使用递归来计算,并将计算结果缓存到Map中,所有的右边分支只需到哈希表中查询,
在哈希表中找到中的正确结果返回即可,不需要再次计算。
在Java8给Map增加了一些新方法,简化了上面这个思路的实现,比如computeIfAbsent(key, function),该函数key可以为需要计算的数字,而function为一个能够递归计算Fibonacci数的lambda表达式,如果key对应的Fibonacci数不在map中,则该lambda表达式能够正确的计算出Fibonacci数
首先要定义一个Map,同时缓存fibonnaci(0) 和 fibonacci(1)的结果
private static Map<Integer,Long> memo = new HashMap<>(); static { memo.put(0,0L); //fibonacci(0) memo.put(1,1L); //fibonacci(1) }剩下的递归部分可以如下定义:
public static long fibonacci(int x) { return memo.computeIfAbsent(x, n -> fibonacci(n-1) + fibonacci(n-2)); }从上面可以看到,如果x的fibonnaci数不在map中,computeIfAbsent方法可以用提供的lambda表达式来计算fibonnaci数的左边部分,然后右边部分直接使用map中缓存的结果,这样就规避了大部分的重复计算。
相关文章推荐
- 关于Java的toString用法
- Sth about Java
- 在eclipse中增加myeclipse的插件
- springMVC JSON的接受和发送
- 第一次写博客,就写点关于我的专业方面的知识吧!
- MyEclipse创建JAX-WS SOAP Web Services
- Spring注入方式二:构造器注入
- Java中Array与ArrayList的主要区别
- Java使用Array类创建多维数组
- Struts2中的Could not find action or result
- Eclipse开发Android应用 找不到平板
- Java 连接池的工作原理
- Java中run(), start(), join(), wait(), yield(), sleep()的使用
- Ubuntu 12.10中MyEclipse 10.6+下载+安装+破解
- Spring注入方式一:setter 方法注入
- java 分页
- 快速排序(Java)
- 深入java集合学习1-集合框架浅析
- 通过jni让java和cpp互相调用(包括编译脚本)
- 使用JavaMail SMTP协议发送邮件