我正在运行这个,但是继续向前飞过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>
答案 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);