例子_实现斐波那数列

"Hello World, Hello Blog"

Posted by wudimingwo on December 15, 2018

版本1.0 for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
      var fun = (function() {

        return function(a,b,n) {
          if(n == 1){
            return a
          };
          if(n == 2){
            return b
          }
          var sum;
          for (var i = 3;i <= n;i++){
            sum = a + b;
            a = b;
            b = sum;
          }
          return sum
        }
      })();

版本2.0递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
      var fun = (function() {

        return function(a,b,n) {
          var sum = a + b;
          n--;
          if(n == 0){
            return a
          }
          if(n == 1){
            return b
          }
          if(n == 2){
            return sum
          }
          return arguments.callee(b,sum,n);
        }
      })();

版本2.1 递归 + 惰性函数(总要练习使用嘛~)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var fun = (function() {

        return function(a,b,n) {
          if(n == 1){
            return a
          }
          if(n == 2){
            return b
          }
          fun = function (a,b,n) {
            var sum = a + b;
            n--;
          	if(n == 2){
          	  return sum
          	}
          	return arguments.callee(b,sum,n);
          }
          return fun(a,b,n);
        }
      })();

这么写,确实能够在后续的递归循环中省去判断1,2的步骤,
但缺点是,一旦运行过n>2,那么重新调用n<2时,
会出现问题.

版本2.2 递归,惰性函数优化版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
      var fun = (function() {
        return function(a,b,n) {
          var fn = arguments.callee;//这个就是神来之笔,惰性函数弄完之后,用来改回最初版本
          if(n == 1){
            return a
          }
          if(n == 2){
            return b
          }
          fun = function (a,b,n) {
            var sum = a + b;
            n--;
          	if(n == 2){
          	  fun = fn;
          	  return sum
          	}
          	return arguments.callee(b,sum,n);
          }
          return fun(a,b,n);
        }
      })();

这个写完,我自己都觉得有点看不懂,略显高级有没有

版本3.0 用私有变量缓存方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
      var fun = (function() {
        var cache = {};
        return function(a, b, n) {
          cache[1] = a;
          cache[2] = b;
          if(cache[n]) {
            return cache[n]
          } else {
            cache[n] = fun(a,b,n-1) + fun(a,b,n-2);
          }
          return cache[n];
        }
      })();
这样也能节省性能,
缺点是会占用缓存,用空间换区速度
写完这个发现,版本2.0的递归写得很丑.

版本4.0 标准递归?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
      var fun = (function() {

        return function(a, b, n) {
          if(n == 1) {
            return a
          }
          if(n == 2) {
            return b
          }
          return fun(a, b, n - 1) + fun(a, b, n - 2)
        }
      })();

这才是标准递归:关系非常的明确,版本2.0的递归还是受到for循环的思维影响.

不过版本2.0的启示是:
    是否所有for循环都可以用递归来代替?
    不过教程里说递归方式有个缺点:性能会低一点,因为函数会层层嵌套,调用多次函数.