web-dev-qa-db-fra.com

Générer une séquence de 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;
}

J'essaie de générer une séquence simple de Fibonacci mais il n'y a pas de sortie. Quelqu'un peut-il me faire savoir ce qui ne va pas?

22
methuselah

Vous n'avez jamais déclaré fib comme étant un tableau. Utilisez var fib = []; pour résoudre ceci.

En outre, vous ne modifiez jamais la variable y, ni ne l'utilisez.

Le code ci-dessous a plus de sens et ne crée pas de variables inutilisées:

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

44
Rob W

Selon le Interview Cake question, la séquence va 0,1,1,2,3,5,8,13,21. Si tel est le cas, cette solution fonctionne et est récursive sans utiliser de tableaux.

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

console.log(fibonacci(4));

Pensez-y comme ça.

   fibonacci(4)   .--------> 2 + 1 = 3
      |          /               |
      '--> fibonacci(3) + fibonacci(2)
            |    ^           
            |    '----------- 2 = 1 + 1 <----------.
1st step -> |                     ^                |
            |                     |                |
            '---->  fibonacci(2) -' + fibonacci(1)-'

Attention, cette solution n’est pas très efficace.

47
Alex Cory

Voici une fonction simple permettant d'itérer la séquence de Fibonacci dans un tableau à l'aide des arguments de la fonction for plutôt que du corps de la boucle:

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]

20
irth

Vous auriez dû déclarer la variable fib comme un tableau (par exemple, var fib = [] ou var fib = new Array()) et je pense que vous êtes un peu confus quant à l'algorithme.
Si vous utilisez un tableau pour stocker la séquence de fibonacci, vous n’avez pas besoin des autres variables auxiliaires (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); 

Cliquez pour la démo

Vous devriez également considérer la méthode récursive (notez qu'il s'agit d'une version optimisée): 

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

et ensuite, après avoir appelé la fonction fibonacci, vous avez toute la séquence dans le champ fib.cache

fib(1000);
console.log(fib.cache);
15
gion_13

Une autre solution consisterait à utiliser es6 - générateur de fonctions .

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
// ...
12
Dimitris Zorbas

Vous n'attribuez pas de valeur à z, qu'attendez-vous donc de ce que y=z; fasse? De même, vous n'êtes jamais réellement en train de lire dans le tableau. On dirait que vous essayez une combinaison de deux approches différentes ici ... essayez de vous débarrasser complètement du tableau, et utilisez simplement:

// Initialization of x and y as before

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

EDIT: L'OP a changé le code après avoir ajouté cette réponse. A l'origine, la dernière ligne de la boucle étaity = z; - et cela a du sens si vous avez initialisé z selon mon code.

Si le tableau est requis plus tard, il est évident qu'il doit encore être rempli - mais sinon, le code que j'ai donné devrait convenir.

9
Jon Skeet

La ration d'or "phi" ^ n/sqrt (5) est asymptotique avec le fibonacci de n, si on arrondit cette valeur, on obtient bien la valeur de fibonacci.

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

Cela fonctionne plus rapidement sur les grands nombres par rapport aux solutions basées sur la récursivité.

6
Kodejuice
function fib(n) {
  if (n <= 1) {
    return n;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

fib(10); // returns 55
3
Mikhail

Il y a aussi une généralisation de la formule de Binet pour les entiers négatifs:

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

Si vous utilisez es6

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


var f = fib(10)
2
sqram

Un moyen rapide d'obtenir ~ 75

ty @geeves pour le catch, j'ai remplacé Math.floor par Math.round, ce qui semble aller jusqu'à 76 où les problèmes de virgule flottante entrent en jeu:/... de toute façon, je ne voudrais pas utiliser la récursion jusqu'à ce point .

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

2
Sparkida
<!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>
2
AKHIL

sparkida, a trouvé un problème avec votre méthode. Si vous cochez la position 10, la valeur renvoyée est 54 et toutes les valeurs suivantes sont incorrectes. Vous pouvez le voir apparaître ici: 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>

1
geeves

Je sais que c’est une question un peu ancienne, mais j’ai réalisé que beaucoup des réponses ici utilisent des boucles for for plutôt que des boucles while.

Parfois, les boucles while sont plus rapides que pour les boucles for, alors je me suis dit que je contribuerais un code qui exécute la séquence de Fibonacci dans une boucle while aussi! Utilisez tout ce que vous trouvez adapté à vos besoins.

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);
1
Steve M. Romain

Une autre implémentation, bien que récursive, est très rapide et utilise une seule fonction inline. Il atteint la limite de précision du nombre javascript 64 bits, en commençant par la 80e séquence (comme tous les autres algorithmes):

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

retournera: 8944394323791464

Ceci est rétro-compatible jusqu’à ECMASCRIPT4 - je l’ai testé avec IE7 et cela fonctionne!

1
Vijay Jagdale

fibonacci 1 000 ... 10 000 ... 100 000

Certaines réponses posent des problèmes lors du calcul de grands nombres de fibonacci. D'autres se rapprochent des nombres en utilisant phi. Cette réponse vous montrera comment calculer une série précise de grands nombres fibonacci sans rencontrer les limitations définies par l'implémentation en virgule flottante de JavaScript.

Ci-dessous, nous générons les 1 000 premiers nombres de fibonacci en quelques millisecondes. Plus tard, nous en ferons 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 ]

Voyons le millième numéro de fibonacci

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

10.000

Cette solution évolue assez bien. Nous pouvons calculer les 10 000 premiers nombres de fibonacci en moins de 2 secondes. À ce stade de la séquence, les nombres ont plus de 2 000 chiffres, bien au-delà de la capacité des nombres à virgule flottante de JavaScript. Reste que notre résultat inclut précis valeurs sans approximations.

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

Bien sûr, toute cette magie se déroule dans Bignum, que nous allons partager maintenant. Pour obtenir une intuition sur la façon dont nous allons concevoir Bignum, rappelez-vous comment vous avez ajouté de grands nombres en utilisant un stylo et du papier enfant ...

  1259601512351095520986368
+   50695640938240596831104
---------------------------
                          ?

Vous ajoutez chaque colonne, de droite à gauche, et lorsqu'une colonne déborde dans les doubles chiffres, en vous rappelant de reporter le 1 sur la colonne suivante ...

                 ... <-001
  1259601512351095520986368
+   50695640938240596831104
---------------------------
                  ... <-472

Ci-dessus, nous pouvons voir que si nous avions deux nombres à 10 chiffres, il faudrait environ 30 additions simples (3 par colonne) pour calculer la réponse. Voici comment nous allons concevoir Bignum pour fonctionner

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

Nous allons faire un test rapide pour vérifier notre exemple ci-dessus

const x =
  fromString ('1259601512351095520986368')

const y =
  fromString ('50695640938240596831104')

console.log (toString (add (x,y)))
// 1310297153289336117817472

Et maintenant, une démonstration complète du programme. Développez-le pour calculer le précis _ 10 000e nombre de fibonacci dans votre propre navigateur! Notez que le résultat est le même que la réponse fournie par 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

J'étais juste curieux de savoir jusqu'où ce petit script pouvait aller. Il semble que la seule limitation est juste le temps et la mémoire. Ci-dessous, nous calculons les 100 000 premiers nombres de fibonacci sans approximation. Les chiffres à ce stade de la séquence sont longs de plus de 20 000, wow! Il faut 3,18 minutes pour terminer, mais le résultat correspond toujours à la réponse de 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
1
user633183

Vous pouvez essayer cette solution de Fibonacci ici

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);
}
1
Akash Dikkaram

Voici des exemples comment écrire fibonacci en utilisant la récursivité, le générateur et la réduction.

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

1
Vlad Bezden

Vous pouvez obtenir du cache pour accélérer l'algorithme ...

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];
        }
    }
};
1
Samuel Pinto

Je voudrais juste contribuer avec une version optimisée des appels de queue par ES6. C'est assez simple;

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

1
Redu

Je voudrais ajouter plus de code comme réponse :), Il n’est jamais trop tard pour coder: 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);

Résultat

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

0
Vikas Bansal
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);
}

Quel que soit le nombre dont nous avons besoin, nous pouvons le donner à la méthode supérieure à fibo et obtenir la série de fibonacci jusqu'au compte.

fibo(20); //output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
0
Nithin

Ce script prendra comme numéro un paramètre indiquant que vous souhaitez que votre séquence de Fibonacci aille.

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;

};
0
Sehul Viras

Débutant, pas trop élégant, mais montre les étapes de base et les déductions en 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); 
0
Enogwe Victor

Fibonacci (une doublure)

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

Fibonacci (récursif)

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

Fibonacci (itératif)

 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

Fibonacci (avec Optimisation des appels en queue )

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

0
Benny Neugebauer

Un autre moyen facile d'y parvenir:

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

0
Mezzanine

Voici une fonction qui affiche l'intégralité d'une séquence de Fibonacci générée lors de l'utilisation de la récursivité:

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;

};

La sortie pour fibonacci(5, 5) sera:

1
1
2
3
5

La valeur affectée à a est la valeur renvoyée de la fonction fibonacci. Sur la ligne suivante, la valeur suivante de la séquence de fibonacci est calculée et poussée à la fin du tableau a

Le paramètre length de la fonction fibonacci permet de comparer la longueur de la séquence constituant le tableau a et doit être identique au paramètre n. Lorsque la longueur de la séquence correspond au paramètre length, le tableau a est envoyé à la console, sinon la fonction renvoie le tableau a et se répète. 

0
Ignat Ospadov

J'aime le fait que (il y a tellement de façons de créer une séquence fibonacci dans JS}. Je vais essayer de reproduire quelques-uns d'entre eux. Le but est de sortir une séquence sur console (comme {n: 6, fiboNum: 8})

Bonne fermeture

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

Générateur ES6 fantaisie

Semblable au schéma de fermeture ci-dessus, utilisant les avantages de la fonction de générateur et de la boucle.

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

Appel de queue récursion

Celui-ci est un peu délicat, car, à la fin de 2018, l'optimisation de TC est toujours un problème. Mais honnêtement - si vous n’utilisez pas d’astuces astucieuses pour permettre au moteur JS par défaut d’utiliser de très gros nombres, il sera pris de vertige et prétend que le prochain numéro de fibonacci est "Infinity" par itération 1477. La pile déborderait probablement quelque part. autour de 10 000 itérations (dépend énormément du navigateur, de la mémoire, etc.). Pourrait probablement être complété par try… catch block ou vérifier si "Infinity" a été atteint.

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)

Cela peut être écrit comme une ligne, si nous gâchons la chose console.log et retournons simplement un nombre:

const fibonacciRTC2 = (n, a = 0, b = 1) => n === 0 ? a : fibonacciRTC2(n - 1, b, a + b);

console.log(fibonacciRTC2(21))

Note importante!

Comme je l'ai découvert en lisant cet article mathIsFun , la séquence de fibonacci est également valable pour les nombres négatifs! J'ai essayé d'implémenter cela dans la forme d'appel de queue récursive ci-dessus comme ça:

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

0
HynekS

Mes 2 centimes:

function fibonacci(num) {
  return Array.apply(null, Array(num)).reduce(function(acc, curr, idx) {
    return idx > 2 ? acc.concat(acc[idx-1] + acc[idx-2]) : acc;
  }, [0, 1, 1]);
}

console.log(fibonacci(10));

0
Jonatas Walker

es6 - Fonctions Symbol.iterator et générateur:

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)
}
0
Aran Dekar

C'est ce que je suis venu avec

//fibonacci numbers
//0,1,1,2,3,5,8,13,21,34,55,89
//print out the first ten fibonacci numbers
'use strict';
function printFobonacciNumbers(n) {
    var firstNumber = 0,
        secondNumber = 1,        
        fibNumbers = [];
    if (n <= 0) {
        return fibNumbers;
    }
    if (n === 1) {
        return fibNumbers.Push(firstNumber);
    }
    //if we are here,we should have at least two numbers in the array
    fibNumbers[0] = firstNumber;
    fibNumbers[1] = secondNumber;
    for (var i = 2; i <= n; i++) {
        fibNumbers[i] = fibNumbers[(i - 1)] + fibNumbers[(i - 2)];
    }
    return fibNumbers;
}

var result = printFobonacciNumbers(10);
if (result) {
    for (var i = 0; i < result.length; i++) {
        console.log(result[i]);
    }
}
0
Rennish Joseph