Bitte erläutern Sie diesen einfachen Code:
public int fibonacci(int n) {
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
Ich bin mit der letzten Zeile verwirrt, vor allem, weil wenn beispielsweise n = 5 ist, Fibonacci (4) + Fibonacci (3) usw. aufgerufen werden, aber ich verstehe nicht, wie dieser Algorithmus den Wert bei Index 5 damit berechnet Methode. Bitte erklären Sie mit viel Detail!
Antworten:
In der Fibonacci-Sequenz ist jedes Element die Summe der beiden vorherigen. Sie haben also einen rekursiven Algorithmus geschrieben.
So,
Jetzt weißt du es schon
fibonacci(1)==1 and fibonacci(0) == 0
. So können Sie anschließend die anderen Werte berechnen.Jetzt,
Und aus der Fibonacci-Sequenz können
0,1,1,2,3,5,8,13,21....
wir sehen, dass für5th element
die Fibonacci-Sequenz zurückkehrt5
.Das Rekursions-Tutorial finden Sie hier .
quelle
Es gibt 2 Probleme mit Ihrem Code:
Der Code
fibonacci(n - 1) + fibonacci(n - 2)
ist sehr falsch.
Das Problem ist, dass es Fibonacci nicht 50 Mal nennt, sondern viel mehr.
Zuerst nennt es Fibonacci (49) + Fibonacci (48),
dann Fibonacci (48) + Fibonacci (47) und Fibonacci (47) + Fibonacci (46).
Jedes Mal, wenn es Fibonacci (n) schlechter wurde, ist die Komplexität exponentiell.
Der Ansatz für nicht rekursiven Code:
quelle
2*fibonacci(n+1)-1
, so dass es mit der gleichen Komplexität wächst wie die Fibonacci-Zahlen selbst, die 1,618 ^ n anstelle von 2 ^ nIm Pseudocode mit n = 5 findet Folgendes statt:
Dies gliedert sich in:
Dies gliedert sich in:
Dies gliedert sich in:
Dies gliedert sich in:
Das führt zu: 5
Wenn die Fibonnacci-Sequenz 1 1 2 3 5 8 ... ist , ist das 5. Element 5. Sie können dieselbe Methode verwenden, um die anderen Iterationen herauszufinden.
quelle
Rekursion kann manchmal schwer zu erfassen sein. Bewerten Sie es einfach auf einem Blatt Papier für eine kleine Anzahl:
Ich bin nicht sicher, wie Java dies tatsächlich bewertet, aber das Ergebnis wird das gleiche sein.
quelle
Sie können Ihre Funktion auch wie folgt vereinfachen:
quelle
Es ist wichtig zu beachten, dass dieser Algorithmus exponentiell ist, da er nicht das Ergebnis zuvor berechneter Zahlen speichert. zB F (n-3) wird 3 mal aufgerufen.
Weitere Einzelheiten finden Sie im Algorithmus von dasgupta, Kapitel 0.2
quelle
Die meisten Antworten sind gut und erklären, wie die Rekursion in Fibonacci funktioniert.
Hier ist eine Analyse der drei Techniken, die auch die Rekursion umfasst:
Hier ist mein Code zum Testen aller drei:
Hier sind die Ergebnisse:
Daher können wir sehen, dass das Auswendiglernen zeitlich und für Schleifenübereinstimmungen am besten ist .
Aber die Rekursion dauert am längsten und sollte im wirklichen Leben vermieden werden. Stellen Sie auch bei Verwendung der Rekursion sicher, dass Sie die Lösung optimieren.
quelle
Dies ist das beste Video, das ich gefunden habe und das die Rekursion und die Fibonacci-Sequenz in Java vollständig erklärt.
http://www.youtube.com/watch?v=dsmBRUCzS7k
Dies ist sein Code für die Sequenz und seine Erklärung ist besser, als ich jemals versuchen könnte, sie abzutippen.
quelle
Für eine rekursive Fibonacci-Lösung ist es wichtig, die Ausgabe kleinerer Fibonacci-Zahlen zu speichern und gleichzeitig den Wert einer größeren Zahl abzurufen. Dies wird als "Auswendiglernen" bezeichnet.
Hier ist ein Code, der das Speichern der kleineren Fibonacci-Werte beim Abrufen einer größeren Fibonacci-Zahl verwendet. Dieser Code ist effizient und stellt nicht mehrere Anforderungen derselben Funktion.
quelle
In der Fibonacci- Sequenz sind die ersten beiden Elemente 0 und 1, wobei jedes andere Element die Summe der beiden vorherigen Elemente ist. dh:
0 1 1 2 3 5 8 ...
Das fünfte Element ist also die Summe aus dem vierten und dem dritten Element.
quelle
Michael Goodrich et al. Bieten einen wirklich cleveren Algorithmus in Datenstrukturen und Algorithmen in Java, um Fibonacci rekursiv in linearer Zeit zu lösen, indem ein Array von [fib (n), fib (n-1)] zurückgegeben wird.
Dies ergibt fib (n) = fibGood (n) [0].
quelle
Hier ist O (1) -Lösung:
Binets Fibonacci-Zahlenformel, die für die obige Implementierung verwendet wurde. Bei großen Eingängen
long
kann durch ersetzt werdenBigDecimal
.quelle
Eine Fibbonacci-Sequenz ist eine Sequenz, die das Ergebnis einer Zahl summiert, wenn sie zum vorherigen Ergebnis hinzugefügt wird, beginnend mit 1.
Sobald wir verstanden haben, was Fibbonacci ist, können wir beginnen, den Code aufzuschlüsseln.
Die erste if-Anweisung sucht nach einem Basisfall, in dem die Schleife ausbrechen kann. Die else if-Anweisung darunter macht dasselbe, könnte aber so umgeschrieben werden ...
Nachdem ein Basisfall erstellt wurde, müssen wir den Aufrufstapel verstehen. Ihr erster Aufruf von "Fibonacci" wird der letzte sein, der auf dem Stapel (Reihenfolge der Aufrufe) aufgelöst wird, da sie in der umgekehrten Reihenfolge aufgelöst werden, aus der sie aufgerufen wurden. Die letzte aufgerufene Methode wird zuerst aufgelöst, dann die letzte, die vor dieser aufgerufen wird, und so weiter ...
Alle Anrufe werden also zuerst getätigt, bevor mit diesen Ergebnissen etwas "berechnet" wird. Bei einer Eingabe von 8 erwarten wir eine Ausgabe von 21 (siehe Tabelle oben).
Fibonacci (n - 1) wird so lange aufgerufen, bis es den Basisfall erreicht, dann wird Fibonacci (n - 2) aufgerufen, bis es den Basisfall erreicht. Wenn der Stapel beginnt, das Ergebnis in umgekehrter Reihenfolge zu summieren, sieht das Ergebnis so aus ...
Sie sprudeln weiter (werden rückwärts aufgelöst), bis die richtige Summe an den ersten Aufruf im Stapel zurückgegeben wird und Sie auf diese Weise Ihre Antwort erhalten.
Allerdings ist dieser Algorithmus sehr ineffizient, da er für jeden Zweig, in den sich der Code aufteilt, das gleiche Ergebnis berechnet. Ein viel besserer Ansatz ist ein "Bottom-up" -Ansatz, bei dem keine Memoisierung (Caching) oder Rekursion (Deep Call Stack) erforderlich ist.
Wie so ...
quelle
Die meisten hier angebotenen Lösungen laufen in O (2 ^ n) -Komplexität. Die Neuberechnung identischer Knoten im rekursiven Baum ist ineffizient und verschwendet CPU-Zyklen.
Wir können die Memoisierung verwenden, um die Fibonacci-Funktion in O (n) -Zeit ausführen zu lassen
Wenn wir der dynamischen Programmierroute von unten nach oben folgen, ist der folgende Code einfach genug, um Fibonacci zu berechnen:
quelle
Warum diese Antwort anders ist
Jede andere Antwort entweder:
(abgesehen davon: keines davon ist tatsächlich effizient; verwenden Sie die Binet-Formel , um das n- te direkt zu berechnen Term )
Schwanz rekursive Fib
Hier ist ein rekursiver Ansatz, der einen doppelt rekursiven Aufruf vermeidet, indem sowohl die vorherige als auch die vorherige Antwort übergeben werden.
quelle
Es ist eine Grundsequenz, die 1 1 2 3 5 8 anzeigt oder eine Ausgabe von 1 1 2 3 5 8 erhält. Es ist eine Sequenz, bei der die Summe der vorherigen Nummer und der aktuellen Nummer als nächstes angezeigt wird.
Versuchen Sie, den Link unter dem Java Tutorial für rekursive Fibonacci-Sequenzen zu sehen
Klicken Sie hier Sehen Sie sich das Java Recursive Fibonacci-Sequenz-Tutorial für die Löffelfütterung an
quelle
Ich denke, das ist ein einfacher Weg:
quelle
Die RanRag-Antwort (akzeptiert) funktioniert einwandfrei, aber dies ist keine optimierte Lösung, bis sie gespeichert wird, wie in Anil-Antwort erläutert.
Für den rekursiven Ansatz unten sind Methodenaufrufe von
TestFibonacci
minimalquelle
quelle
Durch die Verwendung einer internen ConcurrentHashMap, die theoretisch den ordnungsgemäßen Betrieb dieser rekursiven Implementierung in einer Multithread-Umgebung ermöglichen könnte, habe ich eine Fib-Funktion implementiert, die sowohl BigInteger als auch Recursion verwendet. Die Berechnung der ersten 100 Fib-Zahlen dauert ca. 53 ms.
Der Testcode lautet:
quelle
Hier ist eine einzeilige febonacci rekursive:
quelle
Versuche dies
quelle
Wenn Sie größere Zahlen berechnen möchten, sollten Sie BigInteger verwenden.
Ein iteratives Beispiel.
quelle
http://en.wikipedia.org/wiki/Fibonacci_number in weiteren Details
Machen Sie es so einfach wie nötig, ohne dass Sie while-Schleifen und andere Schleifen verwenden müssen
quelle
quelle
Verwendung
while
:Der Vorteil dieser Lösung ist, dass es einfach ist, den Code zu lesen und zu verstehen, in der Hoffnung, dass er hilft
quelle
Eine Fibbonacci-Sequenz ist eine, die das Ergebnis einer Zahl summiert, die wir dann zum vorherigen Ergebnis hinzugefügt haben. Wir sollten mit 1 beginnen. Ich habe versucht, eine Lösung basierend auf dem Algorithmus zu finden, also habe ich den rekursiven Code erstellt und festgestellt, dass ich die behalte vorherige Nummer und ich habe die Position geändert. Ich suche die Fibbonacci-Sequenz von 1 bis 15.
quelle
quelle
Einfache Fibonacci
quelle
@chro ist genau richtig, aber er / sie zeigt nicht den richtigen Weg, um dies rekursiv zu tun. Hier ist die Lösung:
quelle