定义:
公式:
如果 为第一项, 为第二项,那么从第三项开始,以及之后的每一项都等于前两项的和。
在JavaScript 中如何求斐波那契数列中的数呢?
JavaScript中的实现:
《JavaScript 高级程序设计(第四版)》在第 10 章,关于函数尾调用优化代码(P309)列举了一个通过递归函数计算斐波那契数列的例子:
function fib(n) {
if (n < 2) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
console.log(fib(0)); // 0
console.log(fib(1)); // 1
console.log(fib(2)); // 1
console.log(fib(3)); // 2
console.log(fib(4)); // 3
console.log(fib(5)); // 5
console.log(fib(6)); // 8
这个函数会给浏览器带来麻烦,比如说当调用 fib(1000) 的时候。
以下是重构为满足尾调用优化条件的形式,使用两个嵌套的函数,外部函数作为基础框架,内部函数执行递归:
// 基础框架
function fib(n) {
return fibImpl(0, 1, n);
}
// 执行递归
function fibImpl(a, b, n) {
if (n === 0) {
return a;
}
return fibImpl(b, a + b, n - 1);
}
迭代循环的实现:
function fib(n) {
let currNum = 0,
prevNum = 1,
arr = [],
count = 0;
while(count <= n) {
arr.push(currNum);
currNum += prevNum;
prevNum = currNum - prevNum;
count++;
}
return arr[n];
}
console.log(fib(0)); // 0
console.log(fib(1)); // 1
console.log(fib(2)); // 1
console.log(fib(3)); // 2
console.log(fib(4)); // 3
console.log(fib(5)); // 5
console.log(fib(6)); // 8
console.log(fib(10)); // 55
解析:
currNum 是计算斐波那契数列中 的值。
prevNum 是 与 的差值,该差值除第一项以外,可以看出它也是一个斐波那契数列。
它的规律就是:
下一次循环时 currNum 的值是:当前值 + 差值。如上图中左边部分黑色箭头指向所示。
所以,每次循环完应该更新 currNum 的值,用 JavaScript 代码表示就是:
currNum = currNum + prevNUm;
可以简写为:
currNum += prevNum;
下一次循环时 prevNum 的值是:更新后的 currNum 的值 - 当前 prevNum 的值。
prevNum = currNum - prevNum;