Ich hatte das Programm ursprünglich falsch codiert. Anstatt die Fibonacci-Zahlen zwischen einem Bereich zurückzugeben (dh startNumber 1, endNumber 20 sollte = nur die Zahlen zwischen 1 und 20 sein), habe ich für das Programm geschrieben, dass alle Fibonacci-Zahlen zwischen einem Bereich angezeigt werden (dh startNumber 1, endNumber 20) Anzeigen = Erste 20 Fibonacci-Zahlen). Ich dachte, ich hätte einen sicheren Code. Ich verstehe auch nicht, warum das passiert.
startNumber = int(raw_input("Enter the start number here "))
endNumber = int(raw_input("Enter the end number here "))
def fib(n):
if n < 2:
return n
return fib(n-2) + fib(n-1)
print map(fib, range(startNumber, endNumber))
Jemand wies in meinem Teil II (der geschlossen wurde, weil er ein Duplikat war - /programming/504193/how-to-write-the-fibonacci-sequence-in-python-part-ii ) darauf hin, dass ich StartNumber und EndNumber müssen mithilfe einer while-Schleife durch einen Generator geleitet werden. Kann mir bitte jemand die Richtung zeigen, wie das geht? Jede Hilfe ist willkommen.
Ich bin ein lernender Programmierer und bin ein bisschen durcheinander geraten. Ich werde gebeten, ein Programm zu schreiben, das die Fibonacci-Sequenz anhand einer vom Benutzer eingegebenen Start- und Endnummer berechnet und anzeigt (dh startNumber = 20 endNumber = 100 und nur die Zahlen zwischen diesem Bereich anzeigt). Der Trick besteht darin, es inklusiv zu verwenden (was ich in Python nicht weiß? - Ich gehe davon aus, dass dies bedeutet, einen inklusiven Bereich zu verwenden?).
Was ich bisher habe, ist keine eigentliche Codierung, sondern:
- Schreiben Sie die Fib-Sequenzformel auf unendlich
- Zeigen Sie startNumber bis endNumber nur aus der Fib-Sequenz an.
Ich habe keine Ahnung, wo ich anfangen soll, und ich frage nach Ideen oder Einsichten, wie ich das schreiben soll. Ich habe auch versucht, das Fib-Sequenzforum zu schreiben, aber ich verliere mich auch darin.
int(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)))
irgendwelche Ideen verwenden? @AndreaAmbun
über 70 liegt, und mit einemOverflowError
Zeitpunkt explodiert, dern
etwas über 600 liegt. Andere Ansätze können einen
von 1000 oder mehr verarbeiten, ohne zu blasen Präzision verlieren oder verlieren.Effizienter Pythonic-Generator der Fibonacci-Sequenz
Ich habe diese Frage gefunden, als ich versucht habe, die kürzeste Pythonic-Generation dieser Sequenz zu erhalten (später wurde mir klar, dass ich eine ähnliche in einem Python-Verbesserungsvorschlag gesehen hatte ), und ich habe nicht bemerkt, dass jemand anderes meine spezifische Lösung gefunden hat (obwohl die beste Antwort kommt näher, aber immer noch weniger elegant), also hier mit Kommentaren, die die erste Iteration beschreiben, weil ich denke, dass dies den Lesern helfen kann, Folgendes zu verstehen:
und Verwendung:
Drucke:
(Zu Attributionszwecken habe ich kürzlich eine ähnliche Implementierung in der Python-Dokumentation zu Modulen festgestellt , sogar unter Verwendung der Variablen
a
undb
, die ich jetzt vor dem Schreiben dieser Antwort gesehen habe. Ich denke jedoch, dass diese Antwort eine bessere Verwendung der Sprache demonstriert.)Rekursiv definierte Implementierung
Die Online-Enzyklopädie ganzzahliger Sequenzen definiert die Fibonacci-Sequenz rekursiv als
Die prägnante Definition in Python kann wie folgt erfolgen:
Diese genaue Darstellung der mathematischen Definition ist jedoch für Zahlen, die viel größer als 30 sind, unglaublich ineffizient, da jede zu berechnende Zahl auch für jede darunter liegende Zahl berechnet werden muss. Sie können anhand der folgenden Methoden demonstrieren, wie langsam es ist:
Gespeicherte Rekursion für Effizienz
Es kann zur Verbesserung der Geschwindigkeit gespeichert werden (in diesem Beispiel wird die Tatsache ausgenutzt, dass ein Standardschlüsselwortargument bei jedem Aufruf der Funktion dasselbe Objekt ist, aber normalerweise würden Sie aus genau diesem Grund kein veränderbares Standardargument verwenden):
Sie werden feststellen, dass die gespeicherte Version viel schneller ist und Ihre maximale Rekursionstiefe schnell überschreitet, bevor Sie überhaupt daran denken können, auf einen Kaffee aufzustehen. Sie können sehen, wie viel schneller es visuell ist, indem Sie dies tun:
(Es mag so aussehen, als könnten wir nur das Folgende tun, aber es lässt uns den Cache nicht nutzen, da er sich selbst aufruft, bevor setdefault aufgerufen wird.)
Rekursiv definierter Generator:
Als ich Haskell gelernt habe, bin ich in Haskell auf diese Implementierung gestoßen:
Das, was ich momentan in Python am ehesten erreichen kann, ist:
Dies zeigt es:
Es kann jedoch nur bis zur Rekursionsgrenze gehen. Normalerweise 1000, während die Haskell-Version bis zu 100 Millionen erreichen kann, obwohl sie alle 8 GB des Speichers meines Laptops verwendet, um dies zu tun:
Den Iterator verbrauchen, um die n-te Fibonacci-Zahl zu erhalten
Ein Kommentator fragt:
Die itertools-Dokumentation enthält ein Rezept dafür:
und nun:
quelle
setdefault
Aufrufs wird ausgewertet, bevorsetdefault
is.Warum nicht einfach folgendes tun?
quelle
Die Idee hinter der Fibonacci-Sequenz wird im folgenden Python-Code gezeigt:
Dies bedeutet, dass fib eine Funktion ist, die eines von drei Dingen ausführen kann. Es definiert fib (1) == 1, fib (0) == 0 und fib (n) als:
fib (n-1) + fib (n-2)
Wobei n eine beliebige ganze Zahl ist. Dies bedeutet, dass beispielsweise fib (2) auf die folgende Arithmetik erweitert wird:
Wir können fib (3) auf die gleiche Weise mit der unten gezeigten Arithmetik berechnen:
Das Wichtigste dabei ist, dass fib (3) nicht ohne Berechnung von fib (2) berechnet werden kann, was durch Kenntnis der Definitionen von fib (1) und fib (0) berechnet wird. Ein Funktionsaufruf selbst wie die Fibonacci-Funktion wird als Rekursion bezeichnet und ist ein wichtiges Thema bei der Programmierung.
Das klingt nach einer Hausaufgabe, also werde ich den Start- / Endteil nicht für Sie erledigen. Python ist jedoch eine wunderbar ausdrucksstarke Sprache, daher sollte dies sinnvoll sein, wenn Sie Mathematik verstehen, und Sie hoffentlich über Rekursion unterrichten. Viel Glück!
Bearbeiten: Ein möglicher Kritikpunkt an meinem Code ist, dass er nicht die superhandliche Python-Funktionsausbeute verwendet, wodurch die fib (n) -Funktion viel kürzer wird. Mein Beispiel ist allerdings etwas allgemeiner, da nicht viele Sprachen außerhalb von Python tatsächlich Ertrag bringen.
quelle
Zeitliche Komplexität:
Die Caching-Funktion reduziert die normale Methode zur Berechnung von Fibonacci-Reihen von O (2 ^ n) auf O (n), indem die Wiederholungen im rekursiven Baum der Fibonacci-Reihen eliminiert werden:
Code:
quelle
Dies ist sehr effizient, wenn O (log n) grundlegende arithmetische Operationen verwendet werden.
Dieser verwendet O (1) grundlegende arithmetische Operationen, aber die Größe der Zwischenergebnisse ist groß und daher überhaupt nicht effizient.
Dieser berechnet X ^ n im Polynomring Z [X] / (X ^ 2 - X - 1) unter Verwendung der Potenzierung durch Quadrieren. Das Ergebnis dieser Berechnung ist das Polynom Fib (n) X + Fib (n-1), aus dem die n-te Fibonacci-Zahl abgelesen werden kann.
Auch dies verwendet O (log n) arithmetische Operationen und ist sehr effizient.
quelle
n -= 1
richtig funktionieren und es funktioniert auch nicht mitn = 0
. Auf jeden Fall würde es mir wirklich helfen, wenn viel Kontext hinzugefügt würde, um zu erklären, wie diese funktionieren, insbesondere die erste Technik. Ich sehe, Sie haben einen Beitrag bei paulhankin.github.io/FibonacciKanonischer Python-Code zum Drucken der Fibonacci-Sequenz:
Für das Problem "Drucken Sie die erste Fibonacci-Zahl mit mehr als 1000 Stellen":
quelle
Wir wissen das
Und dass die n-te Potenz dieser Matrix uns gibt:
Wir können also eine Funktion implementieren, die einfach die Potenz dieser Matrix zur n-ten -1-Potenz berechnet.
nach allem, was wir wissen, ist die Kraft a ^ n gleich
Am Ende wäre die Fibonacci-Funktion also O (n) ... nichts wirklich anderes als eine einfachere Implementierung, wenn wir das nicht auch wissen
x^n * x^n = x^2n
und die Bewertung vonx^n
daher mit der Komplexität O (log n) erfolgen kann )Hier ist meine Fibonacci-Implementierung mit einer schnellen Programmiersprache:
Dies hat die Komplexität O (log n). Wir berechnen die Potenz von Q mit dem Exponenten n-1 und nehmen dann das Element m00, das Fn + 1 ist und am Leistungsexponenten n-1 genau die n-te Fibonacci-Zahl ist, die wir wollten.
Sobald Sie die schnelle Fibonacci-Funktion haben, können Sie von Startnummer und Endnummer iterieren, um den Teil der Fibonacci-Sequenz zu erhalten, an dem Sie interessiert sind.
Führen Sie natürlich zuerst eine Überprüfung von Anfang und Ende durch, um sicherzustellen, dass sie einen gültigen Bereich bilden können.
Ich weiß, dass die Frage 8 Jahre alt ist, aber ich hatte trotzdem Spaß beim Beantworten. :) :)
quelle
Die Fibonacci-Sequenz lautet :
1, 1, 2, 3, 5, 8, ...
.Das heißt
f(1) = 1
,f(2) = 1
,f(3) = 2
,...
,f(n) = f(n-1) + f(n-2)
.Meine Lieblingsimplementierung (am einfachsten und erreicht dennoch eine Lichtgeschwindigkeit im Vergleich zu anderen Implementierungen) ist folgende:
Prüfung
Zeitliche Koordinierung
Bearbeiten: Eine Beispielvisualisierung für diese Implementierungen.
quelle
Rekursion verwenden:
quelle
Ein anderer Weg, es zu tun:
Das Zuweisen einer Liste zu 'a', das Zuweisen einer Ganzzahl zu 'n' Map und Reduzieren sind zwei der drei leistungsstärksten Funktionen in Python. Hier wird die Karte nur verwendet, um 'n-2' Mal zu iterieren. a [-2:] erhält die letzten beiden Elemente eines Arrays. a.append (x + y) fügt die letzten beiden Elemente hinzu und hängt an das Array an
quelle
Diese sehen alle etwas komplizierter aus, als sie sein müssen. Mein Code ist sehr einfach und schnell:
quelle
OK .. Nachdem Sie es satt haben, alle langwierigen Antworten zu lesen, finden Sie jetzt die folgende sort & süße, ziemlich einfache Möglichkeit, Fibonacci in Python zu implementieren. Sie können es nach Ihren Wünschen verbessern, indem Sie ein Argument oder Benutzereingaben abrufen… oder die Grenzwerte von 10000 ändern. Nach Bedarf ……
Dieser Ansatz funktioniert auch gut. Hier finden Sie die Laufanalyse
quelle
Dies ist eine Verbesserung der Antwort von Mathew Henry:
Der Code sollte b anstatt c drucken
Ausgabe: 1,1,2,3,5 ....
quelle
Verwenden Sie for-Schleife und drucken Sie nur das Ergebnis
Ergebnis
Drucken Sie die
list
mit allen ZahlenErgebnis
quelle
Ergebnisse
[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, 43349443, 731807 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 225851433717, 365435296162, 591286729879, 956722026041, 1548008755920, 2504730781961, 40527380377807
Laufzeit: 0.04298138618469238
quelle
Es gibt eine sehr einfache Methode, um das zu realisieren!
Sie können diesen Code online frei ausführen, indem Sie http://www.learnpython.org/ verwenden.
quelle
Dies kann folgendermaßen erfolgen.
quelle
Nur zum Spaß können Sie in Python 3.8+ einen Zuweisungsausdruck (auch bekannt als Walross-Operator) in einem Listenverständnis verwenden, z.
Mit einem Zuweisungsausdruck können Sie einer Variablen einen Wert zuweisen und ihn im selben Ausdruck zurückgeben. Daher der Ausdruck
entspricht der Ausführung
und Rückgabe des Wertes von
b
.quelle
15 Minuten nach Beginn eines Tutorials, das ich beim Erlernen von Python verwendet habe, wurde der Leser gebeten, ein Programm zu schreiben, das eine Fibonacci-Sequenz aus 3 Eingabenummern berechnet (erste Fibonacci-Nummer, zweite Nummer und Nummer, an der die Sequenz gestoppt werden soll). Das Tutorial hatte nur Variablen behandelt, wenn / dann und Schleifen bis zu diesem Punkt. Noch keine Funktionen. Ich habe mir den folgenden Code ausgedacht:
Wie Sie sehen können, ist es wirklich ineffizient, aber es funktioniert.
quelle
quelle
eval(input())
wird hier nicht benötigt; Ich denkeint(input())
in dem Fall ist besser.Ich habe gerade http://projecteuler.net/problem=2 durchgesehen, das war meine Meinung dazu
quelle
quelle
Vielleicht hilft das
quelle
basierend auf der klassischen Fibonacci-Sequenz und nur zum Wohle der Einzeiler
Wenn Sie nur die Nummer des Index benötigen, können Sie die Reduzierung verwenden (auch wenn die Reduzierung nicht am besten dafür geeignet ist, kann dies eine gute Übung sein).
und um das komplette Array zu erhalten, entfernen Sie einfach das oder (r.pop (0) und 0)
quelle
Wie wäre es mit diesem? Ich denke, es ist nicht so ausgefallen wie die anderen Vorschläge, da es die anfängliche Spezifikation des vorherigen Ergebnisses erfordert, um die erwartete Ausgabe zu erzeugen, aber ich denke, es ist eine sehr lesbare Option, dh alles, was es tut, ist, das Ergebnis und das vorherige Ergebnis bereitzustellen die Rekursion.
Hier ist die Ausgabe:
quelle
Grundsätzlich übersetzt aus Ruby:
...
quelle
quelle
Eine detailliertere Erklärung, wie Memoization für die Fibonacci-Sequenz funktioniert.
quelle
Ich habe versucht, eine rekursive Funktion zu vermeiden, um dieses Problem zu lösen, und habe daher einen iterativen Ansatz gewählt. Ich habe ursprünglich eine auswendig gelernte rekursive Funktion ausgeführt, aber immer wieder die maximale rekursive Tiefe erreicht. Ich hatte auch strenge Speicherziele, so dass Sie sehen werden, dass ich das Array während des Schleifenprozesses so klein wie möglich halte und immer nur 2-3 Werte im Array habe.
Das Erhalten der 6-millionsten Fibonacci-Zahl dauert auf meinem Computer ungefähr 282 Sekunden, während der 600k-Fibonacci nur 2,8 Sekunden dauert. Ich war nicht in der Lage, so große Fibonacci-Zahlen mit einer rekursiven Funktion zu erhalten, selbst einer auswendig gelernten.
quelle