F = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...}
F 0 = 0, F 1 = 1, F n = F n - 1 + F n - 2 ;
n ≥ 0, n ∈ Z
Erste n Fibonacci-Zahlen in Java ermitteln
Angenommen, wir haben die Aufgabe, die ersten n Fibonacci-Zahlen zu ermitteln.-
Fall 0.1:
Eine bestimmte Zahl n kommt zu uns:
int[] arr = new int[n]; arr[0] = 0; arr[1] = 1; for (int i = 2; i < arr.length; ++i) { arr[i] = arr[i - 1] + arr[i - 2]; }
Wir erstellen ein Array der Größe n. Die ersten beiden Elemente sind gleich Null und Eins, und die restlichen Elemente werden erhalten, indem man diese Schleife durchläuft und die vorherigen Zahlen aus dem Array verwendet.
Und wir zeigen:
for (int i = 0; i < arr.length; ++i) { System.out.println(arr[i]); }
Setze int n = 10;
Und wir bekommen:
0 1 1 2 3 5 8 13 21 34
-
Für Fall 1.1 ist die Lösung eigentlich nicht anders:
int[] arr = new int[n]; arr[0] = 1; arr[1] = 1; for (int i = 2; i < arr.length; ++i) { arr[i] = arr[i - 1] + arr[i - 2]; }
Alles, was wir ändern mussten, war das erste Element des Arrays arr[0]: von 0 auf 1. Dementsprechend sind die ersten 10 Elemente:
1 1 2 3 5 8 13 21 34 55
Erste n Fibonacci-Zahlen per Stream
Aber wir wollen unser Niveau zeigen. Sehen wir uns also an, wie diese Lösung mit stream aussehen würde .-
für 0,1:
Stream.iterate(new int[]{0, 1}, arr -> new int[]{arr[1], arr[0]+ arr[1]}) .limit(n) .map(y -> y[0]) .forEach(x -> System.out.println(x));
Die statische Iterate-Methode der Stream- Klasse gibt einen unendlich geordneten Stream zurück, der durch Anwenden der Funktion auf das anfängliche Array arr erstellt wird. In unserem Fall besteht die Funktion darin, die Regel für die Zusammenstellung jedes neuen Arrays basierend auf dem vorherigen festzulegen. Als Ergebnis erhalten wir einen Stream von Arrays:
{0,1} {1,1} {1, 2} {2, 3} {3, 5} {5, 8} {8, 13} {13, 21} {21, 34} {34, 55} …..
Aber es wird unendlich viele davon geben, und deshalb reduzieren wir mit .limit(n) die Anzahl der Elemente auf das erste n (in unserem Fall auf 10).
Allerdings benötigen wir keinen Stream von Arrays, also wählen wir mit .map(y -> y[0]) das erste Element jedes Arrays aus, erhalten einen Stream mit den benötigten Zahlen und geben ihn mit forEach auf der Konsole aus .
Sieht cooler aus, oder?
Da die ersten Elemente 1,1 sind, ist dieser Code auch fast derselbe:Stream.iterate(new int[]{1, 1}, arr -> new int[]{arr[1], arr[0]+ arr[1]}) .limit(n) .map(y -> y[0]) .forEach(x -> System.out.println(x));
Auch hier liegen die Unterschiede im Anfangselement: Anstelle von {0, 1} setzen wir {1, 1}
Tatsächlich werden die Ergebnisse dieselben sein wie im vorherigen Beispiel.
Summe der Fibonacci-Zahlen
Was wäre, wenn wir gebeten würden, die Summe der Fibonacci-Zahlen bis zum n-ten Element einschließlich zu ermitteln? Dies sollte uns keine Schwierigkeiten bereiten. Nehmen wir eine Lösung mit einem Stream und ersetzen Sie forEach durch ein paar andere Methoden:-
für 0,1:
int n = 10; int result = Stream.iterate(new int[]{0, 1}, arr -> new int[]{arr[1], arr[0]+ arr[1]}) .limit(n) .map(t -> t[0]) .mapToInt(Integer::intValue) .sum(); System.out.println(result);
Mit .mapToInt(Integer::intValue) konvertieren wir unseren Stream in einen numerischen IntStream und verwenden seine .sum()-Methode, um die Summe aller Elemente zu erhalten.
- Für den Fall mit 1,1 Anfangselementen setzen wir statt {0, 1} {1, 1}.
Ermitteln der n-ten Zahl in der Fibonacci-Reihe
Manchmal werden Sie aufgefordert, nicht eine Zahlenreihe, sondern speziell die n-te Zahl in der Fibonacci-Reihe zu drucken. Dies erleichtert in der Regel nur die Aufgabe, da Sie bisherige Lösungen hierfür problemlos anpassen können. Nun, wie wäre es mit der Lösung des Problems durch Rekursion?-
für 0,1:
public int getFibonacciValue(int n) { if (n <= 1) { return 0; } else if (n == 2) { return 1; } else { return getFibonacciValue(n - 1) + getFibonacciValue(n - 2); } }
Um den Algorithmus mit 0,1 auszuführen, muss angegeben werden, dass wir beim Versuch, das erste Element zu erhalten, 0 und das zweite 1 erhalten. Tatsächlich müssen wir, wie in vorherigen Lösungen, die ersten beiden festlegen Elemente.
-
Die Implementierung für 1.1 wird etwas anders sein:
public int getFibonacciValue(int n) { if (n == 0) { return 0; } else if (n == 1) { return 1; } else { return getFibonacciValue(n - 1) + getFibonacciValue(n - 2); } }
In diesem Fall müssen wir nur das erste Element auf 1 setzen, da das zweite Element dasselbe ist und die Antwort der Methode dieselbe ist.
Gleichzeitig setzen wir die Reaktion der Methode auf 0, denn wenn wir sie nicht setzen, wird bei 2 als Argument dieselbe Methode rekursiv aufgerufen, jedoch mit Argument 0. Als nächstes wird dieselbe Methode gestartet , aber mit negativen Zahlen und so weiter bis zur negativen Unendlichkeit. Als Ergebnis erhalten wir einen StackOverflowError .
GO TO FULL VERSION