生成斐波纳契数列

时间:2011-10-30 09:50:54

标签: 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;
}

我正在尝试生成一个简单的Fibonacci序列,但没有输出。谁能让我知道什么是错的?

50 个答案:

答案 0 :(得分:51)

根据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)-'

请注意,此解决方案效率不高。

答案 1 :(得分:46)

您从未将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]);
}

答案 2 :(得分:20)

这是一个简单的函数,使用for函数中的参数迭代Fibonacci序列到一个数组中,而不是循环体:

fib = function(numMax){
    for(var fibArray = [0,1], i=0,j=1,k=0; k<numMax;i=j,j=x,k++ ){
        x=i+j;
        fibArray.push(x);
    }
    console.log(fibArray);
}

fib(10)
  

[0,1,1,2,3,5,8,13,21,34,55,89]

答案 3 :(得分:15)

您应该首先将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); 

Click for the demo

您也应该考虑递归方法(请注意,这是一个优化版本):

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);

答案 4 :(得分:12)

另一个答案是使用es6 generator functions

function* fib() {
  var current = a = b = 1;

  yield 1;

  while (true) {
    current = b;

    yield current;

    b = a + b;
    a = current;
  }
}

sequence = fib();
sequence.next(); // 1
sequence.next(); // 1
sequence.next(); // 2
// ...

答案 5 :(得分:9)

您没有为z分配值,那么您希望y=z;做什么?同样地,你实际上从来没有从数组中读取。看起来你正在尝试两种不同方法的组合......尝试完全摆脱阵列,只需使用:

// Initialization of x and y as before

for (i = 2; i <= 10; i++)
{
    alert(x + y);
    z = x + y;
    x = y;
    y = z;
}

编辑:在我添加此答案后,OP更改了代码。最初循环的最后一行 y = z; - 如果你根据我的代码初始化了z,那么是有道理的。

如果稍后需要数组,那么显然需要填充数组 - 但是否则,我给出的代码应该没问题。

答案 6 :(得分:6)

黄金口粮&#34; phi&#34; ^ 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 0.62s

与基于递归的解决方案相比,这在大数字上运行得更快。

答案 7 :(得分:3)

<script type="text/javascript">
  function editProduct(id){
    var url = "editProduct.php?id="+id;
    location.href = url;
  }
</script>

答案 8 :(得分:2)

快速获得~75

ty @geeves为了捕获,我将Math.floor替换为Math.round,似乎将浮点数问题发挥到了76:/ ... 无论哪种方式,我都不希望使用递归,直到那一点。

/**
 * Binet Fibonacci number formula for determining
 * sequence values
 * @param {int} pos - the position in sequence to lookup
 * @returns {int} the Fibonacci value of sequence @pos
 */

var test = [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155,165580141,267914296,433494437,701408733,1134903170,1836311903,2971215073,4807526976,7778742049,12586269025,20365011074,32951280099,53316291173,86267571272,139583862445,225851433717,365435296162,591286729879,956722026041,1548008755920,2504730781961,4052739537881,6557470319842,10610209857723,17167680177565,27777890035288,44945570212853,72723460248141,117669030460994,190392490709135,308061521170129,498454011879264,806515533049393,1304969544928657,2111485077978050,3416454622906707,5527939700884757,8944394323791464,14472334024676221,23416728348467685,37889062373143906,61305790721611591,99194853094755497,160500643816367088,259695496911122585,420196140727489673,679891637638612258,1100087778366101931,1779979416004714189,2880067194370816120,4660046610375530309,7540113804746346429,12200160415121876738,19740274219868223167,31940434634990099905,51680708854858323072,83621143489848422977,135301852344706746049,218922995834555169026];
var fib = function (pos) {
        return Math.round((Math.pow( 1 + Math.sqrt(5), pos) 
            - Math.pow( 1 - Math.sqrt(5), pos)) 
            / (Math.pow(2, pos) * Math.sqrt(5)));
    };

/* This is only for the test */
var max = test.length,
    i = 0,
    frag = document.createDocumentFragment(),
    _div = document.createElement('div'),
    _text = document.createTextNode(''),
    div,
    text,
    err,
    num;
for ( ; i < max; i++) {
    div = _div.cloneNode();
    text = _text.cloneNode();
    num = fib(i);
    if (num !== test[i]) {
        err = i + ' == ' + test[i] + '; got ' + num;
        div.style.color = 'red';
    }
    text.nodeValue = i + ': ' + num;
    div.appendChild(text);
    frag.appendChild(div);
}
document.body.appendChild(frag);

答案 9 :(得分:2)

还有Binet的负整数公式的推广:

static float phi = (1.0f + sqrt(5.0f)) / 2.0f;

int generalized_binet_fib(int n) {
   return round( (pow(phi, n) - cos(n * M_PI) * pow(phi, -n)) / sqrt(5.0f) );
 }

 ...

 for(int i = -10; i < 10; ++i)
    printf("%i ", generalized_binet_fib(i));

答案 10 :(得分:2)

我已经尝试过:可能有效:

console.log(rows);

FIBONACCI here

答案 11 :(得分:2)

如果使用es6

function fib(n, prev = 0, current = 1) {
  return !n ? prev + current : fib(--n, current, prev+current)
}


var f = fib(10)

答案 12 :(得分:2)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <title>fibonacci series</title>
        <script type="text/javascript">
                function generateseries(){
                    var fno = document.getElementById("firstno").value;
                    var sno = document.getElementById("secondno").value;
                    var a = parseInt(fno);
                    var result = new Array();
                    result[0] = a;
                    var b = ++fno;
                    var c = b;
                    while (b <= sno) {  
                    result.push(c);
                    document.getElementById("maindiv").innerHTML = "Fibonacci Series between "+fno+ " and " +sno+ " is " +result;
                        c = a + b;
                        a = b;
                        b = c;
                    }
                }
                function numeric(evt){
                    var theEvent = evt || window.event;
                    var key = theEvent.keyCode || theEvent.which;
                    key = String.fromCharCode(key);
                    var regex = /[0-9]|\./;
                    if (!regex.test(key)) {
                        theEvent.returnValue = false;
                        if (theEvent.preventDefault) 
                            theEvent.preventDefault();
                    }
                }

            </script>
        <h1 align="center">Fibonacci Series</h1>
    </head>
    <body>
        <div id="resultdiv" align="center">
        <input type="text" name="firstno" id="firstno" onkeypress="numeric(event)"><br>
        <input type="text" name="secondno" id="secondno" onkeypress="numeric(event)"><br>
        <input type="button" id="result" value="Result" onclick="generateseries();">
        <div id="maindiv"></div>
        </div>
    </body>
</html>

答案 13 :(得分:2)

我只想通过ES6的尾部调用优化版本做出贡献。这很简单;

var fibonacci = (n, f = 0, s = 1) => n === 0 ? f : fibonacci(--n, s, f + s);
console.log(fibonacci(12));

答案 14 :(得分:1)

如果您需要轻松构建斐波那契数列列表,您可以使用 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]

答案 15 :(得分:1)

斐波纳契1,000 ... 10,000 ... 100,000

在尝试计算大的斐波纳契数时,一些答案会遇到问题。其他人使用phi近似数字。这个答案将向您展示如何计算精确系列的大型斐波纳契数,而不会遇到JavaScript浮点实现设置的限制。

下面,我们在几毫秒内生成前1,000个斐波纳契数。之后,我们会做10万!

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 ]

让我们看看第1,000个斐波纳契数

console.log (seq [1000])
// 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875

<强> 10,000

这个解决方案可以很好地扩展。我们可以在2秒内计算出前10,000个斐波纳契数。在序列的这一点上,数字超过了2000位数字 - 超出了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,000th斐波纳契数!请注意,结果与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

<强> 100000

我很好奇这个小剧本能走多远。似乎唯一的限制就是时间和记忆。下面,我们计算没有近似值的前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

答案 16 :(得分:1)

你可以在这里尝试这个斐波那契解决方案

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);
}

答案 17 :(得分:1)

以下是如何使用递归,生成器和reduce来编写fibonacci的示例。

&#13;
&#13;
'use strict'

//------------- using recursion ------------
function fibonacciRecursion(n) {
  return (n < 2) ? n : fibonacciRecursion(n - 2) + fibonacciRecursion(n - 1)
}

// usage
for (let i = 0; i < 10; i++) {
  console.log(fibonacciRecursion(i))
}


//-------------- using generator -----------------
function* fibonacciGenerator() {
  let a = 1,
    b = 0
  while (true) {
    yield b;
    [a, b] = [b, a + b]
  }
}

// usage
const gen = fibonacciGenerator()
for (let i = 0; i < 10; i++) {
  console.log(gen.next().value)
}

//------------- using reduce ---------------------
function fibonacciReduce(n) {
  return new Array(n).fill(0)
    .reduce((prev, curr) => ([prev[0], prev[1]] = [prev[1], prev[0] + prev[1]], prev), [0, 1])[0]
}

// usage
for (let i = 0; i < 10; i++) {
  console.log(fibonacciReduce(i))
}
&#13;
&#13;
&#13;

答案 18 :(得分:1)

sparkida,发现你的方法存在问题。如果检查位置10,则返回54并导致所有后续值不正确。您可以在此处看到此内容:http://jsfiddle.net/createanaccount/cdrgyzdz/5/

(function() {
  
function fib(n) {
    var root5 = Math.sqrt(5);
    var val1 = (1 + root5) / 2;
    var val2 = 1 - val1;
    var value = (Math.pow(val1, n) - Math.pow(val2, n)) / root5;

    return Math.floor(value + 0.5);
}
    for (var i = 0; i < 100; i++) {
        document.getElementById("sequence").innerHTML += (0 < i ? ", " : "") + fib(i);
    }

}());
<div id="sequence">
    
</div>

答案 19 :(得分:1)

我知道这是一个古老的问题,但我意识到这里的许多答案都是利用循环而不是循环。

有时,虽然循环比循环更快,所以我想我也会在while循环中贡献一些运行Fibonacci序列的代码!使用您认为适合您需求的任何东西。

function fib(length) {
  var fibArr = [],
    i = 0,
    j = 1;
  fibArr.push(i);
  fibArr.push(j);
  while (fibArr.length <= length) {
    fibArr.push(fibArr[j] + fibArr[i]);
    j++;
    i++;
  }
  return fibArr;
};
fib(15);

答案 20 :(得分:1)

你可以获得一些缓存来加速算法...

var tools = {

    fibonacci : function(n) {
        var cache = {};

        // optional seed cache
        cache[2] = 1;
        cache[3] = 2;
        cache[4] = 3;
        cache[5] = 5;
        cache[6] = 8;

        return execute(n);

        function execute(n) {
            // special cases 0 or 1
            if (n < 2) return n;

            var a = n - 1;
            var b = n - 2;

            if(!cache[a]) cache[a] = execute(a);
            if(!cache[b]) cache[b] = execute(b);

            return cache[a] + cache[b];
        }
    }
};

答案 21 :(得分:0)

另一种实现,虽然递归非常快并且使用单个内联函数。它达到了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测试了它,它可以工作!

答案 22 :(得分:0)

我不久前遇到的一个解决方案

function fib(n) {
 if(n<0) throw new Error('Incorrect number in a Fibonacci sequence');

 let p = 1.618; //phi number which is also (1 + Math.sqrt(5)) / 2
 return Math.round(Math.pow(p, n) / Math.sqrt(5));
}

时间 O(1)

空间 O(1)

答案 23 :(得分:0)

<!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>

答案 24 :(得分:0)

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)

干杯!

答案 25 :(得分:0)

为了减少时间和优化性能,我们可以在 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))

答案 26 :(得分:0)

    // 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]

答案 27 :(得分:0)

时下另一个通过 memoization 进行冗余计算的示例。

    "extract-i18n": {
      "builder": "@angular-devkit/build-angular:extract-i18n",
      "options": {
        "browserTarget": "rubywebclient:build"
      },
      "configurations" : {
        "en": {
           //your configuration 
          "outputPath": "locale/",
          "outFile": "messages.en.untranslated.xlf",
          "i18nFormat": "xlf",
          "i18nLocale": "en"
        }
      }
    },

答案 28 :(得分:0)

另一个解决方案可能是:

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]

答案 29 :(得分:0)

您可以参考以下简单的递归函数。

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.

答案 30 :(得分:0)

最近有人问我这个问题,这是我的解决方法:

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));
}


就像前面提到的,上述递归解决方案对性能有非常严重的影响。幸运的是,有一个解决方案,它称为备忘录:

// 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));

答案 31 :(得分:0)

我喜欢这样的事实,有很多方法可以在JS中创建斐波那契序列。我将尝试重现其中的一些。目标是将序列输出到控制台(例如{n: 6, fiboNum: 8}

良好的'ol闭包

// 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);

花式ES6生成器

类似于上面的关闭模式,利用了生成器功能和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下一个斐波那契数是“ Infinity”。堆栈可能会在某个地方溢出大约1万次迭代(很大程度上取决于浏览器,内存等)。可以用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

答案 32 :(得分:0)

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)
}

答案 33 :(得分:0)

斐波纳契(单线)

function fibonacci(n) {
  return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
}

Fibonacci(递归)

&#13;
&#13;
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
&#13;
&#13;
&#13;

Fibonacci(迭代)

&#13;
&#13;
 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
&#13;
&#13;
&#13;

斐波纳契(Tail Call Optimization

&#13;
&#13;
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
&#13;
&#13;
&#13;

答案 34 :(得分:0)

这是一个在使用递归时完整显示生成的Fibonacci序列的函数:

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数组的末尾。

length函数的fibonacci参数用于比较a数组序列的长度,并且必须与n参数相同。当序列的长度与length参数匹配时,a数组将输出到控制台,否则函数将返回a数组并重复。

答案 35 :(得分:0)

此脚本将使用数字作为参数,您希望Fibonacci序列继续运行。

function calculateFib(num) {
    var fibArray = [];
    var counter = 0;

    if (fibArray.length == 0) {
        fibArray.push(
            counter
        );
        counter++
    };

    fibArray.push(fibArray[fibArray.length - 1] + counter);

    do {
        var lastIndex = fibArray[fibArray.length - 1];
        var snLastIndex = fibArray[fibArray.length - 2];
        if (lastIndex + snLastIndex < num) {
            fibArray.push(lastIndex + snLastIndex);
        }

    } while (lastIndex + snLastIndex < num);

    return fibArray;

};

答案 36 :(得分:0)

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]

答案 37 :(得分:0)

这就是我想出来的

 final RadioButton rbPublic = (RadioButton) findViewById(R.id.rb_group_create_group_public);
        final RadioButton rbCloses = (RadioButton) findViewById(R.id.rb_group_create_group_closed);
        final RadioButton rbSecret = (RadioButton) findViewById(R.id.rb_group_create_group_secret);

        rbPublic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    rbCloses.setChecked(!isChecked);
                    rbSecret.setChecked(!isChecked);
                }
            }
        });
        rbCloses.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    rbPublic.setChecked(!isChecked);
                    rbSecret.setChecked(!isChecked);
                }
            }
        });
        rbSecret.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    rbCloses.setChecked(!isChecked);
                    rbPublic.setChecked(!isChecked);
                }
            }
        });

答案 38 :(得分:0)

我想添加更多代码作为答案:),编码永远不会太晚:P

function fibonacciRecursive(a, b, counter, len) {
    if (counter <= len) {
        console.log(a);
        fibonacciRecursive(b, a + b, counter + 1, len);
    }
}

fibonacciRecursive(0, 1, 1, 20);

<强>结果

  

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

答案 39 :(得分:0)

实现这一目标的另一种简单方法:

// declare the array starting with the first 2 values of the fibonacci sequence
    var fibonacci = [0,1];
    
    function listFibonacci() {
    // starting at array index 1, and push current index + previous index to the array
        for (var i = 1; i < 10; i++) {
            fibonacci.push(fibonacci[i] + fibonacci[i - 1]);
        }
        console.log(fibonacci);
    }
    
    listFibonacci();
    

答案 40 :(得分:0)

初学者,不是太优雅,但在JavaScript中显示基本步骤和演绎

/* Array Four Million Numbers */
var j = [];
var x = [1,2];
var even = [];
for (var i = 1;i<4000001;i++){
   j.push(i);
    }
// Array Even Million
i = 1;
while (i<4000001){
    var k = j[i] + j[i-1];
    j[i + 1]  = k;
    if (k < 4000001){
        x.push(k);
        }
    i++;
    }
var total = 0;
for (w in x){
    if (x[w] %2 === 0){
        even.push(x[w]);
        }
 }
for (num in even){
    total += even[num];
 }
console.log(x);
console.log(even);
console.log(total); 

答案 41 :(得分:0)

我的2美分:

&#13;
&#13;
activate_shopify_session_with_id(@domain, shop_token)
&#13;
&#13;
&#13;

答案 42 :(得分:-1)

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);

答案 43 :(得分:-1)

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));

答案 44 :(得分:-1)

更好的选择是使用递归,但以下示例可以帮助您理解逻辑!

编辑:更正,递归最终将耗尽系统资源而不归档预期结果。以下示例使用简单的逻辑,它可以处理得非常快......

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);

答案 45 :(得分:-1)

不需要慢循环,生成器或递归函数(有或没有缓存)。这是使用Arrayreduce的快速单行。

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, ...]

答案 46 :(得分:-1)

我认为这个很容易理解:

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));

答案 47 :(得分:-1)

您可以使用递归并以功能方式缓存结果。

const fibonacci = (n, cache = {1: 1, 2: 1}) =>
  cache[n] || (cache[n] = fibonacci(--n, cache) + fibonacci(--n, cache));
  
console.log(fibonacci(1000));
console.log(fibonacci(100));
console.log(fibonacci(10));

答案 48 :(得分:-1)

(function fib(max,i,j) {
  i = i||this[0];j=j||this[1];
  if (max!==0) {
    this.push(i+j);
    max--;
    return fib.bind(this, max, j, i+j)();
  } else {
    return this;
  }
}.bind([0,1], 10))();

结果:[0,1,1,2,3,5,8,13,21,34,55,89]

答案 49 :(得分:-1)

这是另一个有适当尾调用的人。

递归内部fib函数可以重用堆栈,因为生成下一个数字所需的一切(数字数组)作为参数传入,没有其他表达式可供评估。

然而,在ES2015中引入了尾调用优化。

另外一个缺点是它在每次迭代中获得数组长度(但只有一次)以生成以下数字并在其索引上获取数组的元素(它比pop或splice或其他数组方法更快)但是我没有对整个解决方案进行性能测试。

&#13;
&#13;
var fibonacci = function(len) {
  var fib = function(seq) {
    var seqLen = seq.length;
    if (seqLen === len) {
      return seq;
    } else {
      var curr = seq[seqLen - 1];
      var prev = seq[seqLen - 2];
      seq[seqLen] = curr + prev;
      return fib(seq);
    }
  }
  return len < 2 ? [0] : fib([0, 1]);
}

console.log(fibonacci(100));
&#13;
&#13;
&#13;