代码改变世界

javascript递归一例

2009-03-12 13:07  wlstyle  阅读(1865)  评论(0)    收藏  举报

有这么一个场景,假设有n级的台阶。每走一步可以有三种走法 要不走一步,要不走两步,要不走三步问总共有几种走法。

这是一个可以利用递归的场景。可以使用这个方法算出共n级台阶的走法。

 1 var countWay=function(n){
 2         if(n==1){
 3             return 1;
 4         }else if(n==2){
 5             return 2
 6         }else if(n==3){
 7             return 4
 8         }else{
 9            return countWay(n-1)+countWay(n-2)+countWay(n-3);
10         }
11       }

但是当级数的增高,递归执行的时间过长所以出现脚本退出的提示。这里可以利用记忆技术来解决这个问题。

 1  function memorise(fn,cache){
 2         cache=cache || {};
 3         return  function(arg){
 4             if(!(arg in cache)){
 5                 cache[arg]=fn( arguments.callee,arg);
 6             }
 7             return cache[arg]
 8         }

10       }

可以这么使用这个函数

var countWay=memorise(function(recur,n){return recur(n-1)+recur(n-2)+recur(n-3)},{'1':1,'2':2,'3':4});

alert(countWay(100));这样来计算。

对于这个记忆函数。利用了函数的闭包来存储每一次调用返回的值。当调用memorise函数的时候。返回一个函数。这个函数判断在cache中是否已经存在这个值。

如果不存在这个值。那么调用该函数本身来计算这个值。并将这个计算出的这个值返回。这样就减少了对函数调用次数的,从而减少了运行的时间。如果要查看.cache是否真的有所有的值。那么可以这样些。

 1 function memorise(fn,cache){
 2         cache=cache || {};
 3          return   function(arg){
 4             if(!(arg in cache)){
 5                 cache[arg]=fn( arguments.callee,arg);
 6             }
 7             if(arg==100){
 8                 console.log(cache);
 9             }
10             return  cache[arg];
11         }
12       }
13       var s=memorise(function(recur,n){return recur(n-1)+recur(n-2)+recur(n-3)},{'1':1,'2':2,'3':4});
14       console.log(s(100))

 引用 Nicholas C. Zakasde大牛的mem方法.

 总结:将用到的值存起来,不要临时去算出这个值。这样效率比较高。