为什么我的代码无法计算Fibonnaci 30以上

时间:2015-07-03 15:26:12

标签: javascript

我正在运行这个,但是继续向前飞过Fibonnaci 30的数字只是继续加载。

这是我的代码:

<script type="text/javascript">
function fib(n) {

    if (n <= 1) {
        return 1;
    } else {
        return (fib(n - 1) + fib(n - 2) + fib(n - 3));
    }
}

function start() {
    document.getElementById("result").innerHTML = fib(30)
}

window.addEventListener("load", start, false)
</script>

2 个答案:

答案 0 :(得分:3)

这里的问题是,当你增加传入的初始数字时,它会在内部以指数方式调用自己。

当您致电fib(3)时,它会在内部再次呼叫fib 6次。如果你打电话给fib(4),它会在内部自称12次。 fib(5)将完成25次。每个人都会以指数方式获得更多。

当你到达30岁时,它自称104551006次(yes really),这开始需要一段时间。数字越大,情况就越糟糕。

这是另一种递归的fibonnacci计算器,改编自this psuedocode answer

function fib(term, val, prev)
{
    if (!val)
        val = 1;
    if (!prev)
        prev = 0;

    if(term == 0) return prev;
    if(term == 1) return val;
    return fib(term - 1, val+prev, val);
}

alert(fib(6)); //gives 8, the 6th number in the sequence

答案 1 :(得分:2)

坚实的实施始终是最佳途径,因此James Thorpe的实施是你应该去的。但是,减少对递归函数的调用的另一种方法是memoization。本质上,memoization缓存了对具有一组特定参数的函数的调用结果。

原始代码(已修改为返回实际的Fibonnaci序列):

var call_count = 0;

function fib(n) {
  call_count++;
  if (n <= 1) {
    return 1;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

alert('fib(15): ' + fib(15) + '; call_count: ' + call_count);

通知代码

var call_count = 0;

// See http://www.sitepoint.com/implementing-memoization-in-javascript/
function memoize(func) {
  var memo = {};
  var slice = Array.prototype.slice;

  return function() {
    var args = slice.call(arguments);  // Turn 'arguments' into a real array

    if (args in memo)
      return memo[args];
    else
      return (memo[args] = func.apply(this, args));

  }
}

function fib(n) {
  call_count++;
  if (n <= 1) {
    return 1;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

// Replace fib with memoized version
fib = memoize(fib);

alert('fib(30): ' + fib(30) + '; call_count: ' + call_count);