2016-06-12 10 views
0

Ich möchte die ersten 5 Zahlen in der Fibonacci-Folge beginnend mit 1 und 2 drucken. Ich erwarte, dass dieser Code 1,2,3,5,8 druckt, wenn ich auf den Knopf klicke, aber irgendwie druckt er nur die letzte Zahl ist in diesem Fall 8. Und wenn ich danach mehrmals auf die Schaltfläche klicke, wird immer 2 gedruckt. Warum verhält es sich so?Fibonacci-Sequenzimplementierung verhält sich nicht wie erwartet

/* 
 
Fibonacci sequence is calculated by the formula An = An-1 + An-2 
 
@param prev An-2 
 
@param next An-1 
 
@param n the first n numbers to print 
 
*/ 
 
var count = 0; // keeps track of which number we are on 
 
function fibonacci(prev, next, n) { 
 
    // Need to subtract 2 or else it will print the first 7 numbers instead of 5 
 
    return count++ < n - 2 ? fibonacci(Math.max(prev,next), prev+next, n) + "," : next; 
 
} 
 

 
document.querySelector('button').addEventListener('click', function() { 
 
    console.log(fibonacci(1, 2, 5)); 
 
});
<button>Click me</button>

+3

hinweis: wo setzen sie 'count' zurück? – BeyelerStudios

+0

Genauer gesagt druckt es '8 ,,,' – 1983

+0

Sie fügen Ihrer Zeichenfolge nicht 'prev' hinzu. – 1983

Antwort

2

Sie verwenden nur console.log mit dem letzten Ergebnis. Wenn Sie alle von ihnen protokollieren möchten, sollten Sie es innerhalb der rekursiven Funktion verwenden.

Und das zweite Mal, wenn Sie auf die Schaltfläche klicken, funktioniert es nicht, da count global ist. Sie könnten es innerhalb des Ereignis-Listeners auf 0 zurücksetzen, aber vermeiden Sie besser globale Variablen.

function fibonacci(current, next, n) { 
 
    if(n > 0) { 
 
    console.log(current); 
 
    fibonacci(next, current + next, n-1); 
 
    } 
 
} 
 
document.querySelector('button').addEventListener('click', function() { 
 
    fibonacci(1, 2, 5); 
 
});
<button>Click me</button>

+2

Es sieht so aus, als ob das OP eine einzelne Zeichenfolge als Ergebnis haben möchte. Vielleicht diese Variation einbeziehen? 'var fib = Funktion (a, b, n) {return n === 1? a: a + ',' + fib (b, a + b, n-1); }; ' – 1983

+0

Das ist genau das, was ich brauchte. Danke Oriol und @FizzyTea – Dummy

1

Sie console.log() der Rückgabewert von fibonacci(1,2,5), die genau eine Zahl ist. Sie drucken nirgendwo in Ihren rekursiven Funktionsaufrufen. Also wird natürlich nur das Endergebnis Ihrer Funktion gedruckt. Wenn Sie intermediäre Ergebnisse wünschen, geben Sie console.log(prev) vor Ihrer Rückgabebestätigung in fibonacci().

Dies löst Ihre erste Ausgabe.


Für das zweite Problem müssen Sie berücksichtigen, wie Ihre Variablen funktionieren. count ist außerhalb der Funktion fibonacci definiert und wird deshalb nicht automatisch zurückgesetzt oder nur weil die Funktion endet. Das bedeutet: nachdem die Funktion zum ersten Mal ausgeführt wurde (und als Nebeneffekt, count auf 3 zu setzen), behält die Variable count ihren Wert 3. Wenn Sie die Funktion das nächste Mal ausführen, wird count++ < n - 2 sofort auf false ausgewertet, weil 4 < 3 falsch ist. So wird next zurückgegeben, die 2 auf der ersten Iteration ist.

Um dies zu beheben, restrucutre Ihre Funktion in einer Weise, dass es count-0 zurücksetzt, wenn die letzte Rekursion durchgeführt wird, bevor es next zurückkehrt (Sie dies innerhalb der ternären Anweisung nicht tun können, müssen Sie es zu einem regelmäßigen refractore wenn -else)

+0

Sehr gute Erklärung.Vielen Dank. +1. – Dummy

0

Verwenden wir neueste Technologien.

<!DOCTYPE html> 
<html> 
<head> 
    <title>Fibonacci</title> 
    <meta charset="utf-8" /> 
    <script type="text/javascript"> 
     'use strict'; 
     function* fibonacci(cur, nxt) {//generator function 
      //let cur=0,nxt=1; 
      yield cur; 
      yield nxt; 
      while(true){ 
       [cur,nxt]=[nxt,cur+nxt];//swap 
       yield nxt; 
      } 
     } 

     function getNumbers(){ 
      var a = document.getElementById('cur').value-0;//instead of parseInt 
      var b = document.getElementById('nxt').value-0; 
      var n = document.getElementById('cnt').value-0; 
      var fi = fibonacci(a,b);//init generator 
      var fiNums = [];//init result array 
      for (var i = 0; i < n; i++) { 
       var tmp=fi.next();//{value:1, done:false} 
       fiNums.push(tmp.value); 
      } 
      //output result 
      document.getElementById('output').innerHTML = fiNums.join(', '); 
     } 

//get all series in once 
function getNumbersOld(){ 
    var a = document.getElementById('cur').value-0; 
    var b = document.getElementById('nxt').value-0; 
    var n = document.getElementById('cnt').value-0; 
    var fiNums = [b,a]; 
    for (var i = 2; i < n; i++) { 
     fiNums.unshift(fiNums[0]+fiNums[1]); 
    } 
    document.getElementById('output').innerHTML = fiNums.reverse().join(', '); 
} 
    </script> 
</head> 
<body> 
Generate Fibonacci series <br /> 
Current:<input type="number" id="cur" value="1" /> 
    Next:<input type="number" id="nxt" value="1" /> 
    Count:<input type="number" id="cnt" value="5" /> 
    <button onclick="getNumbersOld()">Get Numbers</button> 
    <div id="output"></div> 
</body> 
</html> 
+1

Ihre Implementierung ist unnötig kompliziert. Ich bevorzuge Rekursion über Schleifen jeden Tag. Wenn du in einer Zeile fertig werden kannst. Dann tun Sie es in einer Zeile – Dummy

+0

Siehe Update. Ich hoffe, das ist was du willst. –

0

Basierend auf den Antworten die globalen Variable in Bezug auf und, wie ich nicht das Ergebnis jeden rekursive Aufruf von anderen gedruckt wurde, konnte ich eine endgültige richtige Lösung für mein Problem erhalten.

function fibanocci(prev, next, n) { 
    /* 
     n - 2 is here so it will print the first n numbers in the Fibonacci sequence 
     instead of n + 2 numbers because we have to account for the 2 initial numbers, 
     1 and 2 in this case, and I don't want the client to account for these 2 initial 
     numbers themselves. Math.abs(n-2) so the recursion will stop when n is 1 so the 
     call stack will not get bloated and throw an exception. 
    */ 
    return n > Math.abs(n-2) ? prev + "," + fibanocci(Math.max(prev,next), prev + next, --n) : prev; 
} 

document.querySelector('button').addEventListener('click', function() { 
    console.log(fibonacci(1, 2, 5)); 
}); 
Verwandte Themen