我認爲這是一個更好的功能,因爲它使用一個線性迭代過程以適當的尾遞歸
function fib(n) {
function iter(xs, i, a, b) {
if (i === 0) return xs;
return iter(xs.concat(b), i-1, b, a+b);
}
return iter([0], n, 0, 1);
}
實例
fib(0);
//=> [ 0 ]
fib(1);
//=> [ 0, 1 ]
fib(2);
//=> [ 0, 1, 1 ]
fib(3);
//=> [ 0, 1, 1, 2 ]
fib(4);
//=> [ 0, 1, 1, 2, 3 ]
fib(5);
//=> [ 0, 1, 1, 2, 3, 5 ]
fib(6);
//=> [ 0, 1, 1, 2, 3, 5, 8 ]
fib(10);
//=> [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]
說明
的iter
函數取4個狀態變量
xs
- 的FIB系列,[ 0 ]
i
initalized - 用於終止遞歸遞減迭代器,與n
a
初始化 - 第一FIB編號,與0
b
初始化 - 第二個fib編號,用1
初始化
這種工作方式是,一旦i
已達到0
,xs
將返回。
讓我們看看如何fib(5)
計算
// xs i a b
// -----------------------------
iter([0], 5, 0, 1);
iter([0,1], 4, 1, 1);
iter([0,1,1], 3, 1, 2);
iter([0,1,1,2], 2, 2, 3);
iter([0,1,1,2,3], 1, 3, 5);
iter([0,1,1,2,3,5], 0, 5, 8);
// -----------------------------
//=> [0,1,1,2,3,5]
ES6
使用U型組合子與ES6,你可以得到相同的功能的一個非常簡化版本
// ES6
let fib = n => (
f => f(f, [0], n, 0, 1)
)(
(f, xs, i, a, b) => i === 0 ? xs : f(f, xs.concat(b), i-1, b, a+b)
);
fib(10);
//=> [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]
酷!
如果你正在存儲整個序列歷史記錄,它可能會消耗大量的內存來處理大的'n' –