【发布时间】:2011-12-18 03:47:07
【问题描述】:
var x = 0;
var y = 1;
var z;
fib[0] = 0;
fib[1] = 1;
for (i = 2; i <= 10; i++) {
alert(x + y);
fib[i] = x + y;
x = y;
z = y;
}
我正在尝试生成一个简单的斐波那契数列,但没有输出。
谁能告诉我怎么回事?
【问题讨论】:
标签: javascript fibonacci
var x = 0;
var y = 1;
var z;
fib[0] = 0;
fib[1] = 1;
for (i = 2; i <= 10; i++) {
alert(x + y);
fib[i] = x + y;
x = y;
z = y;
}
我正在尝试生成一个简单的斐波那契数列,但没有输出。
谁能告诉我怎么回事?
【问题讨论】:
标签: javascript fibonacci
我喜欢 在 JS 中有很多方法可以创建斐波那契数列。我将尝试复制其中的一些。目标是将序列输出到控制台(如{n: 6, fiboNum: 8})
// The IIFE form is purposefully omitted. See below.
const fiboGenClosure = () => {
let [a, b] = [0, 1];
let n = 0;
return (fiboNum = a) => {
[a, b] = [b, a + b];
return {
n: n++,
fiboNum: fiboNum
};
};
}
// Gets the sequence until given nth number. Always returns a new copy of the main function, so it is possible to generate multiple independent sequences.
const generateFiboClosure = n => {
const newSequence = fiboGenClosure();
for (let i = 0; i <= n; i++) {
console.log(newSequence());
}
}
generateFiboClosure(21);
类似于上面的闭包模式,利用了生成器函数和for..of循环的优点。
// The 'n' argument is a substitute for index.
function* fiboGen(n = 0) {
let [a, b] = [0, 1];
while (true) {
yield [a, n++];
[a, b] = [b, a + b];
}
}
// Also gives a new sequence every time is invoked.
const generateFibonacci = n => {
const iterator = fiboGen();
for (let [value, index] of iterator) {
console.log({
n: index,
fiboNum: value
});
if (index >= n) break;
}
}
generateFibonacci(21);
这个有点棘手,因为现在是 2018 年末,TC 优化仍然是一个问题。但老实说——如果你不使用任何聪明的技巧来让默认的 JS 引擎使用一个非常大的数字,它会变得头晕目眩,并声称下一个斐波那契数在迭代 1477 时是“无穷大”。堆栈可能会在某个地方溢出大约迭代 10 000 次(很大程度上取决于浏览器、内存等……)。可以通过 try...catch 块或检查是否达到“Infinity”来填充。
const fibonacciRTC = (n, i = 0, a = 0, b = 1) => {
console.log({
n: i,
fibonacci: a
});
if (n === 0) return;
return fibonacciRTC(--n, ++i, b, a + b);
}
fibonacciRTC(21)
如果我们去掉console.log这个东西并简单地返回一个数字,它可以写成单行:
const fibonacciRTC2 = (n, a = 0, b = 1) => n === 0 ? a : fibonacciRTC2(n - 1, b, a + b);
console.log(fibonacciRTC2(21))
当我阅读this mathIsFun article 时发现,斐波那契数列也适用于负数!我尝试在上面的递归尾调用表单中实现它:
const fibonacciRTC3 = (n, a = 0, b = 1, sign = n >= 0 ? 1 : -1) => {
if (n === 0) return a * sign;
return fibonacciRTC3(n - sign, b, a + b, sign);
}
console.log(fibonacciRTC3(8)); // 21
console.log(fibonacciRTC3(-8)); // -21
【讨论】:
黄金比例 "phi" ^ n / sqrt(5) 对 n 的斐波那契是渐近的,如果我们将该值向上取整,我们确实得到了斐波那契值。
function fib(n) {
let phi = (1 + Math.sqrt(5))/2;
let asymp = Math.pow(phi, n) / Math.sqrt(5);
return Math.round(asymp);
}
fib(1000); // 4.346655768693734e+208 in just a few milliseconds
与基于递归的解决方案相比,这在大数上运行得更快。
【讨论】:
Math.sqrt(5) 和 phi。作为参考,我在 fib(7) 之前对其进行了测试,并且运行良好。使用说明:fib(0) = 0
根据Interview Cake 问题,顺序为0,1,1,2,3,5,8,13,21。如果是这种情况,则此解决方案有效且无需使用数组即可递归。
function fibonacci(n) {
return n < 1 ? 0
: n <= 2 ? 1
: fibonacci(n - 1) + fibonacci(n - 2)
}
console.log(fibonacci(4))
这样想。
fibonacci(4) .--------> 2 + 1 = 3
| / |
'--> fibonacci(3) + fibonacci(2)
| ^
| '----------- 2 = 1 + 1 <----------.
1st step -> | ^ |
| | |
'----> fibonacci(2) -' + fibonacci(1)-'
请注意,这个解决方案不是很有效。
【讨论】:
我不久前遇到的一个解决方案
function fib(n) {
if(n<0) throw new Error('Incorrect number in a Fibonacci sequence');
const phi = (1 + Math.sqrt(5)) / 2;
return Math.round(Math.pow(phi, n) / Math.sqrt(5));
}
时间 O(1)
空间 O(1)
参考:http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibFormula.html
【讨论】:
如果您需要轻松构建斐波那契数列,可以使用array destructuring assignment 来缓解您的痛苦:
function fibonacci(n) {
let fibList = [];
let [a, b] = [0, 1]; // array destructuring to ease your pain
while (a < n) {
fibList.push(a);
[a, b] = [b, a + b]; // less pain, more gain
}
return fibList;
}
console.log(fibonacci(10)); // prints [0, 1, 1, 2, 3, 5, 8]
【讨论】:
斐波那契 1,000 ... 10,000 ... 100,000
在尝试计算较大的斐波那契数时,一些答案会遇到问题。其他人正在使用 phi 来近似数字。此答案将向您展示如何计算 精确 一系列大型斐波那契数,而不会遇到 JavaScript 浮点实现设置的限制。
下面,我们在几毫秒内生成前 1,000 个斐波那契数。以后,我们会做100,000!
const { fromInt, toString, add } =
Bignum
const bigfib = function* (n = 0)
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n >= 0) {
yield toString (a)
_ = a
a = b
b = add (b, _)
n = n - 1
}
}
console.time ('bigfib')
const seq = Array.from (bigfib (1000))
console.timeEnd ('bigfib')
// 25 ms
console.log (seq.length)
// 1001
console.log (seq)
// [ 0, 1, 1, 2, 3, ... 995 more elements ]
让我们看看第 1000 个斐波那契数
console.log (seq [1000])
// 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
10,000
这个解决方案可以很好地扩展。我们可以在 2 秒内计算出前 10,000 个斐波那契数。在序列中的这一点上,数字长度超过 2,000 位——远远超出了 JavaScript 浮点数的容量。尽管如此,我们的结果仍包含 精确 值而没有进行近似。
console.time ('bigfib')
const seq = Array.from (bigfib (10000))
console.timeEnd ('bigfib')
// 1877 ms
console.log (seq.length)
// 10001
console.log (seq [10000] .length)
// 2090
console.log (seq [10000])
// 3364476487 ... 2070 more digits ... 9947366875
当然,所有这些魔法都发生在Bignum,我们现在将分享。要了解我们将如何设计 Bignum,请回想一下您小时候是如何使用笔和纸来添加大数的……
1259601512351095520986368
+ 50695640938240596831104
---------------------------
?
您从右到左添加每一列,当一列溢出到两位数时,请记住将 1 带到下一列...
... <-001
1259601512351095520986368
+ 50695640938240596831104
---------------------------
... <-472
在上面,我们可以看到,如果我们有两个 10 位数字,则需要大约 30 次简单的加法(每列 3 次)来计算答案。这就是我们设计Bignum 工作的方式
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
Array.from (b) .reverse () .join ('')
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
我们将运行一个快速测试来验证上面的示例
const x =
fromString ('1259601512351095520986368')
const y =
fromString ('50695640938240596831104')
console.log (toString (add (x,y)))
// 1310297153289336117817472
现在是一个完整的程序演示。展开它以在您自己的浏览器中计算精确第 10,000 个斐波那契数!注意,结果和wolfram alpha提供的答案一样
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
Array.from (b) .reverse () .join ('')
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
const { fromInt, toString, add } =
Bignum
const bigfib = function* (n = 0)
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n >= 0) {
yield toString (a)
_ = a
a = b
b = add (b, _)
n = n - 1
}
}
console.time ('bigfib')
const seq = Array.from (bigfib (10000))
console.timeEnd ('bigfib')
// 1877 ms
console.log (seq.length)
// 10001
console.log (seq [10000] .length)
// 2090
console.log (seq [10000])
// 3364476487 ... 2070 more digits ... 9947366875
100,000
我只是好奇这个小脚本能走多远。似乎唯一的限制是时间和记忆。下面,我们不使用近似值计算前 100,000 个斐波那契数。序列中此时的数字长度超过 20,000 位,哇!完成需要 3.18 分钟,但结果仍然与 wolfram alpha 的答案匹配
console.time ('bigfib')
const seq = Array.from (bigfib (100000))
console.timeEnd ('bigfib')
// 191078 ms
console.log (seq .length)
// 100001
console.log (seq [100000] .length)
// 20899
console.log (seq [100000])
// 2597406934 ... 20879 more digits ... 3428746875
BigInt
JavaScript 现在原生支持 BigInt。这允许非常快速地计算大整数 -
function* fib (n)
{ let a = 0n
let b = 1n
let _
while (n >= 0) {
yield a.toString()
_ = a
a = b
b = b + _
n = n - 1
}
}
console.time("fib(1000)")
const result = Array.from(fib(1000))
console.timeEnd("fib(1000)")
document.body.textContent = JSON.stringify(result, null, 2)
body {
font-family: monospace;
white-space: pre;
}
【讨论】:
<!DOCTYPE html>
<html>
<body>
<p id="fibonacci">Fibonacci</p>
<script>
var fibo = fibonacci()
function* fibonacci() {
var x = 1, y = 1, z = 0
yield* [x, y];
while(true) {
z = x + y, x = y, y = z;
yield z;
}
}
setInterval(
() => document.getElementById("fibonacci").innerHTML = fibo.next().value
, 1000);
</script>
</body>
</html>
【讨论】:
let maxNum = 10; // can change as per your desired length
const fibonnaci = (terms) => {
let series = [0, 1], a = 1, b = 0, f = 0;
for (let i = 0; i < terms; b = a, a = f, i++) {
f = b + a
series.push(f)
}
console.log(series) // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …]
}
fibonnaci(maxNum)
干杯!
【讨论】:
为了减少时间和优化性能,我们可以在 fibo 中使用 memoization,因为 fibo(40) 会花费太多时间来计算结果,所以要处理这种情况,memoization 就出现了。 [Memoization 基本上是用来缓存基于输入的值,简单来说我们可以说我们存储了以前值的结果。
function fibo(n, prevValues = []) {
if (prevValues[n] != null) {
return prevValues[n];
}
let result;
if (n <= 2) {
result = 1
} else {
result = fibo(n - 1, prevValues) + fibo(n - 2, prevValues);
}
prevValues[n] = result;
return result;
}
console.log(fibo(41))
【讨论】:
我已经尝试过了:它可能会起作用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fibonacci</title>
<style>
* {
outline: 0px;
margin: 0px;
}
input[type="number"] {
color: blue;
border: 2px solid black;
width: 99.58vw;
}
</style>
</head>
<body>
<div id="myDiv" style="color: white;background-color: blue;">Numbers Here</div>
<input type="number" id="input1" oninput="fibonacciProgram(this.value)" placeholder="Type Some Numbers Here">
<script>
function fibonacciProgram(numberCount) {
let resultElement = document.getElementById("myDiv");
resultElement.innerHTML = " ";
if (isNaN(numberCount) || numberCount <= 0) {
resultElement.innerHTML = "please enter a number";
return;
}
let firstBox = 0;
let secondBox = 1;
let swichBox;
let entries = [];
entries.push(secondBox);
while (numberCount > 1) {
swichBox = firstBox + secondBox;
entries.push(swichBox);
firstBox = secondBox;
secondBox = swichBox;
numberCount--;
}
resultElement.innerHTML = entries.join(', ');
}
</script>
</body>
</html>
【讨论】:
// using recursive approach and in one line
const fib = x => (x <= 1)? x : fib (x - 1) + fib(x -2);
fib(15); // 610
// display the 15 first
Array.from({ length: 15 }, (v, i) => fib(i));
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
// using memoization approach
function fibonacci(num, memo) {
memo = memo || {};
if (memo[num]) return memo[num];
if (num === 0) return 0;
if (num === 1) return 1;
return memo[num] = fibonacci(num - 1, memo) + fibonacci(num - 2, memo);
}
fibonacci(15); // 610
// display the 15 first
Array.from({ length: 15 }, (v, i) => fibonacci(i));
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
【讨论】:
实现此目的的另一种简单方法:
function listFibonacci(n) {
// declare the array starting with the first 2 values of the fibonacci sequence
// starting at array index 1, and push current index + previous index to the array
for (var fibonacci = [0, 1], i = 1; i < n; i++)
fibonacci.push(fibonacci[i] + fibonacci[i - 1])
return fibonacci
}
console.log( listFibonacci(10) )
【讨论】:
listFibonacci(0) & listFibonacci(1)
如果使用 ES2015
const fib = (n, prev = 0, current = 1) => n
? fib(--n, current, prev + current)
: prev + current
console.log( fib(10) )
【讨论】:
var fib = (n, prev = 0, current = 1) => !n ? prev + current : fib(--n, current, prev+current); 似乎显示的是第 n+3 项而不是第 n 项。将测试更改为 !(n-3) 可以解决此问题;但是,这意味着 fib(0)、fib(1) 和 fib(2) 不起作用。
另一种解决方案可能是:
const fib = (num) => {
if(num === 0) return 0;
const arr=[0,1];
let counter=2;
while(counter <=num){
arr[counter]=arr[counter -1] + arr[counter -2]
counter ++
}
return arr
}
此函数根据给定的限制返回一个斐波那契数列数组。
fib(5) // returns [0, 1, 1, 2, 3, 5]
【讨论】:
你可以参考下面的简单递归函数。
function fib(n){
if (n <= 2) return 1;
return fib(n-1) + fib(n-2);
}
console.log(fib(10)) //55 // Pass on any value to get fibonacci of.
【讨论】:
fib(0) 或 fib(1) 也是错误的
我最近被问到这个问题,这是我的解决方案:
function fib(n) {
const arr = [0,1]; // the inital array, we need something to sum at the very beginning
for (let i = 2; i <= n; i++) { // we want the last number, so don't forget the '=' sign
let a = arr[i-1]; // previous Number
let b = arr[i-2]; // the one before that
arr.push(a+b); // push the result
}
return arr; // if you want the n-th number, just return arr[n] or arr.length - 1
}
console.log(fib(4));
递归解决方案是:
// NOTE: This has extremly bad performance => Exponential time complexity 2^n
function fib(n) {
if (n < 2) {
return n;
}
return fib(n-1) + fib(n-2);
}
console.log('The n-th fibonacci number: ', fib(6));
console.log('The entire fibonacci sequence: ');
// Let's see the entire fibonacci sequence
for (let i = 0; i <= 6; i++) {
console.log(fib(i));
}
如前所述,上述递归解决方案对性能的影响非常糟糕。幸运的是,有一个解决方案,它被称为 memoization:
// LET'S CREATE A MEMO FUNCTION
// (and use it on the recursive **fib** function from above):
// We want to pass in a function which is going to, eventually,
// use this utility function
function memo(fn) {
const cache = {};
// let's make it reusable, and by that I mean, let's assume that
// we don't know the number of arguments that will be eventually passed in
return function(...args) {
// if we already call this function with the same args?
// YES => return them
if(cache[args]) {
console.log('cached', args[0]);
return cache[args];
}
// otherwise, we want to call our function
// (the one using this 'memo' function) and pass in the arguments
// w/ the help of 'apply'
const res = fn.apply(this, args);
cache[args] = res;
// we want to store the result, so later if we'll be able to
// return that if the args don't change
console.log('not cached', args[0]);
return res; // don't forget to return the result of it :)
}
}
// Now, let's use the memoized function:
// NOTE: Remember the above function has to change in a way
// that it calls the memoized function instead of itself
function fastFib(n) {
// SAME LOGIC AS BEFORE
if (n<2) {
return n;
}
// But, here is where the 'magic' happens
// Very important: We want to call the instantiated 'fibMemo' function
// and NOT 'fastFib', cause then it wouldn't be so fast, right :)
return fibMemo(n-1) + fibMemo(n-2);
}
// DO NOT CALL IT, JUST PASS IT IN
const fibMemo = memo(fastFib);
// HERE WE WANT TO PASS IN THE ARGUMENT
console.log(fibMemo(6));
【讨论】:
您从未将fib 声明为数组。使用var fib = []; 解决这个问题。
此外,您永远不会修改 y 变量,也不会使用它。
下面的代码更有意义,而且它不会创建未使用的变量:
var i;
var fib = []; // Initialize array!
fib[0] = 0;
fib[1] = 1;
for (i = 2; i <= 10; i++) {
// Next fibonacci number = previous + one before previous
// Translated to JavaScript:
fib[i] = fib[i - 2] + fib[i - 1];
console.log(fib[i]);
}
【讨论】:
es6 - Symbol.iterator 和生成器函数:
let fibonacci = {
*[Symbol.iterator]() {
let pre = 0, cur = 1
for (;;) {
[ pre, cur ] = [ cur, pre + cur ]
yield cur
}
}
}
for (let n of fibonacci) {
if (n > 1000)
break
console.log(n)
}
【讨论】:
var a = -1;
var b=0;
var temp =0;
var arry = [];
for(var i=1;i<100;i++){
temp = a+b;
a=b;
b=temp;
arry.push(b*-1);
}
console.log(arry);
【讨论】:
另一种实现,虽然递归非常快并且使用单个内联函数。它达到了 javascript 64 位数字精度限制,从第 80 个序列开始(与所有其他算法一样): 例如,如果您想要第 78 项(最后一个括号中是 78):
(function (n,i,p,r){p=(p||0)+r||1;i=i?i+1:1;return i<=n?arguments.callee(n,i,r,p):r}(78));
将返回:8944394323791464
这一直向后兼容到 ECMASCRIPT4 - 我用 IE7 对其进行了测试,它可以工作!
【讨论】:
这是一个在使用递归时完整显示生成的斐波那契数列的函数:
function fibonacci (n, length) {
if (n < 2) {
return [1];
}
if (n < 3) {
return [1, 1];
}
let a = fibonacci(n - 1);
a.push(a[n - 2] + a[n - 3]);
return (a.length === length)
? a.map(val => console.log(val))
: a;
};
fibonacci(5, 5) 的输出将是:
1
1
2
3
5
分配给a 的值是fibonacci 函数的返回值。在下一行,计算斐波那契数列的下一个值并将其推送到a 数组的末尾。
fibonacci函数的length参数用于比较a数组的序列长度,必须与n参数相同。当序列的长度与length参数匹配时,将a数组输出到控制台,否则函数返回a数组并重复。
【讨论】:
您可以在这里尝试这个斐波那契解决方案
var a = 0;
console.log(a);
var b = 1;
console.log(b);
var c;
for (i = 0; i < 3; i++) {
c = a + b;
console.log(c);
a = b + c;
console.log(a);
b = c + a;
console.log(b);
}
【讨论】:
您应该首先将fib 变量声明为数组(例如var fib = [] 或var fib = new Array()),我认为您对算法有点困惑。
如果使用数组存储斐波那契数列,则不需要其他辅助变量(x,y,z):
var fib = [0, 1];
for(var i=fib.length; i<10; i++) {
fib[i] = fib[i-2] + fib[i-1];
}
console.log(fib);
你也应该考虑递归方法(注意这是优化版本):
function fib(n, undefined){
if(fib.cache[n] === undefined){
fib.cache[n] = fib(n-1) + fib(n-2);
}
return fib.cache[n];
}
fib.cache = [0, 1, 1];
然后,在你调用斐波那契函数之后,你就有了fib.cache 字段中的所有序列:
fib(1000);
console.log(fib.cache);
【讨论】:
更好的选择是使用递归,但以下示例可以帮助您理解逻辑!
编辑:更正,递归最终会耗尽系统的资源,而不归档预期的结果。下面这个例子使用了简单的逻辑,而且处理速度非常快……
var sequence = [0,1];
var range = 10;
for(var i = 0; i < range-2; i++){
sequence.push(sequence[i]+sequence[i+1]);
}
console.log(sequence);
【讨论】:
function getFibonacciNumbers(n) {
var sequence = [0, 1];
if (n === 0 || n === 1) {
return sequence[n];
}
else {
for (var i = 2; i < n; i++ ) {
var sum = sequence[i - 1] + sequence[i - 2];
sequence.push(sum);
}
return sequence;
}
}
console.log(getFibonacciNumbers(0));
console.log(getFibonacciNumbers(1));
console.log(getFibonacciNumbers(9));
【讨论】:
function fib(n) {
if (n <= 1) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
fib(10); // returns 55
【讨论】:
斐波那契(单线)
function fibonacci(n) {
return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
}
斐波那契(递归)
function fibonacci(number) {
// n <= 1
if (number <= 0) {
return n;
} else {
// f(n) = f(n-1) + f(n-2)
return fibonacci(number - 1) + fibonacci(number - 2);
}
};
console.log('f(14) = ' + fibonacci(14)); // 377
斐波那契(迭代)
function fibonacci(number) {
// n < 2
if (number <= 0) {
return number ;
} else {
var n = 2; // n = 2
var fn_1 = 0; // f(n-2), if n=2
var fn_2 = 1; // f(n-1), if n=2
// n >= 2
while (n <= number) {
var aa = fn_2; // f(n-1)
var fn = fn_1 + fn_2; // f(n)
// Preparation for next loop
fn_1 = aa;
fn_2 = fn;
n++;
}
return fn_2;
}
};
console.log('f(14) = ' + fibonacci(14)); // 377
斐波那契(Tail Call Optimization)
function fibonacci(number) {
if (number <= 1) {
return number;
}
function recursion(length, originalLength, previous, next) {
if (length === originalLength)
return previous + next;
return recursion(length + 1, originalLength, next, previous + next);
}
return recursion(1, number - 1, 0, 1);
}
console.log(`f(14) = ${fibonacci(14)}`); // 377
【讨论】:
不需要慢循环、生成器或递归函数(有或没有缓存)。这是一个使用Array 和reduce 的快速单行代码。
ECMAScript 6:
var fibonacci=(n)=>Array(n).fill().reduce((a,b,c)=>a.concat(c<2?c:a[c-1]+a[c-2]),[])
ECMAScript 5:
function fibonacci(n){
return Array.apply(null,{length:n}).reduce(function(a,b,c){return a.concat((c<2)?c:a[c-1]+a[c-2]);},[]);
}
在 Chrome 59 (Windows 10) 中测试:
fibonacci(10); // 0 ms -> (10) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
JavaScript 在到达 Infinity 之前最多可以处理 1476 个数字。
fibonacci(1476); // 11ms -> (1476) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...]
【讨论】:
我觉得这个简单易懂:
function fibonacci(limit) {
let result = [0, 1];
for (var i = 2; i < limit; i++) {
result[result.length] = result[result.length - 1] + result[result.length - 2];
}
return result;
}
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
console.log(fibonacci(10));
【讨论】:
function fibo(count) {
//when count is 0, just return
if (!count) return;
//Push 0 as the first element into an array
var fibArr = [0];
//when count is 1, just print and return
if (count === 1) {
console.log(fibArr);
return;
}
//Now push 1 as the next element to the same array
fibArr.push(1);
//Start the iteration from 2 to the count
for(var i = 2, len = count; i < len; i++) {
//Addition of previous and one before previous
fibArr.push(fibArr[i-1] + fibArr[i-2]);
}
//outputs the final fibonacci series
console.log(fibArr);
}
无论我们需要什么计数,我们都可以将它提供给上面的 fibo 方法,让斐波那契数列达到计数。
fibo(20); //output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
【讨论】: