memoization提高递归效率

从开通博客到目前为止,也有一年了,刚开始的写了一篇工做的感想,而后就一直不知道写什么,看园子里的文章实在是很专业,怕本身写的太水。可是,写一些东西总归是好的,因而就看成是记笔记同样,开始写第一篇技术类的文章。javascript

最近打算巩固增强javascript知识,因此开始作codewars, 经过解决codewars的kata,真的了解了一些没有注意的知识点。最近就了解了一下,之前没有听过的memoization.java

codewars的题目是这样写的:数组

给一个整数n,写一个函数返回fibonacci数列的第n个数,而且不但愿执行函数后还要去泡杯咖啡来等待结果~囧~,而后提出了'implement the memoization solution'。因为以前没有据说过memoization,因此就去google了一下了解到底什么是memoization。缓存

 

一  memoization简介
函数

 

维基百科是这样描述的:优化

memoization最初是用来优化计算机程序使之计算的更快的技术,是经过存储调用函数的结果而且在一样参数传进来的时候返回结果。大部分应该是在递归函数中使用。google

memoization这个词是在1968年被Donald Michie创造出来的,它源于拉丁语memoradum,在英语中一般简写为memo,所以就有了将一个函数的返回结果暂存入某个变量中的意思。(翻译水平略渣,若有不对,欢迎指正拍砖)。spa

 

二  经过Fibonacci例子进一步了解翻译

 

通常实现输出fibonacci数列第n个数,应该使用递归调用,代码是这样的:code

function fibonacci(n){
   if(n==0||n==1){
        return n;
    }
    return fibonacci(n-1) + fibonacci(n-1);
}        

因为递归函数会重复调用不少遍函数,传入一样的参数,获得一样的结果,实际是重复实现同一个行为,就会致使效率很低。好比执行fibonacci(5),就要先算出fibonacci(4)和fibonacci(3);而计算fibonacci(4)和fibonacci(3),就要计算fibonacci(3),fibonacci(2)和fibonacci(2),fibonacci(1),这就像一个树同样,每一个分支都要重复计算,直到获得fibonacci(1)为止。以下图所示: 

 

这样就会致使须要计算不少遍的重复数据,因而想到是否可以把已经计算过的结果暂时存起来,等到下次用的时候直接取出结果。因此定义了一个数组用来存放计算过的数据,而后在须要的时候从数组中查询,这样就会省去不须要的计算,提升程序的效率。代码以下:

var fibonacci = (function(){
  var cache = [];           //定义一个空的存放缓存的数组
  return function(n){      
    if(n === 0 || n === 1){
      return n;
    }else{
      cache[n-1] = cache[n-1]||fibonacci(n-1); //先从cache数组里查询结果,若是没找到的话在计算
      cache[n-2] = cache[n-2]||fibonacci(n-2);
      return cache[n-1]+cache[n-2];
    }
  }
})();

三 总结

memorization 能够把函数每次的返回值存在一个数组或者对象中,在接下来的计算中能够直接读取已经计算过而且返回的数据,不用重复屡次相同的计算。这种方法可用于部分递归中以提升递归的效率。

最后,本文若是有任何有问题的地方,欢迎批评指正。

相关文章
相关标签/搜索