Was ist der beste Ansatz zur Berechnung des größten Primfaktors einer Zahl?
Ich denke, das effizienteste wäre das Folgende:
- Finden Sie die niedrigste Primzahl, die sich sauber teilt
- Überprüfen Sie, ob das Ergebnis der Teilung prim ist
- Wenn nicht, finden Sie den nächstniedrigeren
- Gehe zu 2.
Ich gehe davon aus, dass es einfacher ist, die kleinen Primfaktoren zu berechnen. Ist das ungefähr richtig? Welche anderen Ansätze sollte ich prüfen?
Bearbeiten: Ich habe jetzt erkannt, dass mein Ansatz zwecklos ist, wenn mehr als 2 Primfaktoren im Spiel sind, da Schritt 2 fehlschlägt, wenn das Ergebnis ein Produkt von zwei anderen Primzahlen ist, weshalb ein rekursiver Algorithmus benötigt wird.
Nochmals bearbeiten: Und jetzt habe ich festgestellt, dass dies immer noch funktioniert, da die zuletzt gefundene Primzahl die höchste sein muss. Daher würde jedes weitere Testen des Nicht-Primergebnisses aus Schritt 2 zu einer kleineren Primzahl führen.
quelle
1.
Finden Sie eine Zahl, die sich klar teilt (für i = 2 bis int (sqr (num))),2.
dividieren Sie durch diese Zahl (num = num / i) und wiederholen Sie den3.
Antworten:
Tatsächlich gibt es mehrere effizientere Möglichkeiten, um Faktoren mit großen Zahlen zu finden (für kleinere funktioniert die Testabteilung recht gut).
Eine Methode, die sehr schnell ist, wenn die Eingangszahl zwei Faktoren hat, die sehr nahe an ihrer Quadratwurzel liegen, ist als Fermat-Faktorisierung bekannt . Es nutzt die Identität N = (a + b) (a - b) = a ^ 2 - b ^ 2 und ist leicht zu verstehen und zu implementieren. Leider ist es im Allgemeinen nicht sehr schnell.
Die bekannteste Methode zum Faktorisieren von Zahlen mit einer Länge von bis zu 100 Stellen ist das quadratische Sieb . Als Bonus kann ein Teil des Algorithmus problemlos parallel verarbeitet werden.
Ein weiterer Algorithmus, von dem ich gehört habe, ist Pollards Rho-Algorithmus . Es ist nicht so effizient wie das quadratische Sieb im Allgemeinen, scheint aber einfacher zu implementieren zu sein.
Nachdem Sie sich entschieden haben, wie eine Zahl in zwei Faktoren aufgeteilt werden soll, finden Sie hier den schnellsten Algorithmus, den ich mir vorstellen kann, um den größten Primfaktor einer Zahl zu finden:
Erstellen Sie eine Prioritätswarteschlange, in der zunächst die Nummer selbst gespeichert wird. Bei jeder Iteration entfernen Sie die höchste Zahl aus der Warteschlange und versuchen, sie in zwei Faktoren aufzuteilen (wobei 1 natürlich nicht einer dieser Faktoren sein darf). Wenn dieser Schritt fehlschlägt, ist die Zahl eine Primzahl und Sie haben Ihre Antwort! Andernfalls fügen Sie die beiden Faktoren in die Warteschlange ein und wiederholen.
quelle
Hier ist der beste Algorithmus, den ich kenne (in Python)
Die obige Methode wird im
O(n)
schlimmsten Fall ausgeführt (wenn die Eingabe eine Primzahl ist).BEARBEITEN:
Unten ist die
O(sqrt(n))
Version, wie im Kommentar vorgeschlagen. Hier ist noch einmal der Code.quelle
O(sqrt(n))
schlimmsten Fall ein" - Nein, es läuft imO(n)
schlimmsten Fall ein (zn
. B. wenn es Prime ist)Meine Antwort basiert auf der von Triptychon , verbessert sich aber erheblich. Es basiert auf der Tatsache, dass nach 2 und 3 alle Primzahlen die Form 6n-1 oder 6n + 1 haben.
Ich habe kürzlich einen Blog-Artikel geschrieben erklärt wird, wie dieser Algorithmus funktioniert.
Ich würde es wagen, dass eine Methode, bei der kein Primalitätstest (und keine Siebkonstruktion) erforderlich ist, schneller abläuft als eine, bei der diese verwendet werden. Wenn dies der Fall ist, ist dies hier wahrscheinlich der schnellste Algorithmus.
quelle
while (multOfSix - 1 <= n)
JavaScript-Code:
Anwendungsbeispiel:
Hier ist ein Beispiel für den Code :
quelle
Ähnlich wie @Triptych Antwort, aber auch anders. In diesem Beispiel wird eine Liste oder ein Wörterbuch nicht verwendet. Code ist in Ruby geschrieben
quelle
Alle Zahlen können als Produkt von Primzahlen ausgedrückt werden, z.
Sie können diese finden, indem Sie einfach bei 2 beginnen und einfach weiter teilen, bis das Ergebnis kein Vielfaches Ihrer Zahl ist:
Mit dieser Methode müssen Sie keine Primzahlen berechnen: Es handelt sich bei allen um Primzahlen, da Sie die Zahl bereits mit allen vorhergehenden Zahlen so weit wie möglich faktorisiert haben.
quelle
currFactor = 3513642
, wissen wir, dass 12345678987667 eine Primzahl ist, und sollten sie als Antwort zurückgeben. Stattdessen setzt dieser Code die Aufzählung bis 12345678987667 selbst fort. Das ist 3.513.642x langsamer als nötig.quelle
while
Schleife durchläuft also diei
Werte von2,2,2,2,2,2,2,2,2,2,2,2, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5
. Alle 60 Iterationen. Aber für (10 ^ 12 + 39) gibt es (10 ^ 12 + 38) Iterationeni=2,3,4,5,6,...,10^12+39
. Selbst wenn 10 ^ 10 Operationen eine Sekunde dauern, dauert 10 ^ 12 100 Sekunden. Aber es werden wirklich nur 10 ^ 6 Iterationen benötigt, und wenn 10 ^ 10 Operationen eine Sekunde dauern, würde 10 ^ 6 eine 1 / 10.000stel Sekunde dauern.long n = 2*1000000000039L
? Funktioniert es so schnell wie es sollte? (Können Sie Ihren Code auch mithilfe einerreturn;
Anweisung vereinfachen ?) (Wenn du willst, dass ich aufhöre, dich zu stupsen, sag es einfach;))Die einfachste Lösung ist ein Paar gegenseitig rekursiver Funktionen.
Die erste Funktion generiert alle Primzahlen:
Die zweite Funktion gibt die Primfaktoren einer bestimmten Zahl
n
in aufsteigender Reihenfolge zurück.n
.Der größte Primfaktor von
n
ist die letzte durch die zweite Funktion gegebene Zahl.Dieser Algorithmus erfordert eine Lazy List oder eine Sprache (oder Datenstruktur) mit Call-by-Need- Semantik.
Zur Verdeutlichung ist hier eine (ineffiziente) Implementierung der oben genannten in Haskell:
Um dies schneller zu machen, muss man nur klüger erkennen, welche Zahlen Primzahlen und / oder Faktoren sind
n
, aber der Algorithmus bleibt derselbe.quelle
Es gibt einige Modulo-Tests, die überflüssig sind, da n niemals durch 6 geteilt werden kann, wenn alle Faktoren 2 und 3 entfernt wurden. Sie können nur Primzahlen für i zulassen, was in mehreren anderen Antworten hier gezeigt wird.
Sie könnten das Sieb von Eratosthenes hier tatsächlich verflechten:
Siehe auch diese Frage .
quelle
Mir ist bewusst, dass dies keine schnelle Lösung ist. Posting als hoffentlich leichter verständliche langsame Lösung.
quelle
Python Iterativer Ansatz durch Entfernen aller Primfaktoren aus der Zahl
quelle
Ich verwende einen Algorithmus, der die Zahl weiterhin durch den aktuellen Primfaktor dividiert.
Meine Lösung in Python 3:
Eingabe:
10
Ausgabe:5
Eingabe:
600851475143
Ausgabe:6857
quelle
Hier ist mein Versuch in c #. Der letzte Ausdruck ist der größte Primfaktor der Zahl. Ich habe nachgesehen und es funktioniert.
quelle
quelle
Berechnet den größten Primfaktor einer Zahl mithilfe der Rekursion in C ++. Die Funktionsweise des Codes wird nachfolgend erläutert:
quelle
Hier ist mein Ansatz, um schnell den größten Primfaktor zu berechnen. Es basiert auf der Tatsache, dass modifiziert
x
keine Nicht-Primfaktoren enthält. Um dies zu erreichen, teilen wir,x
sobald ein Faktor gefunden wird. Dann müssen Sie nur noch den größten Faktor zurückgeben. Es wäre schon Prime.Der Code (Haskell):
quelle
Der folgende C ++ - Algorithmus ist nicht der beste, funktioniert jedoch für Zahlen unter einer Milliarde und ist ziemlich schnell
quelle
Fand diese Lösung im Web von "James Wang"
quelle
Primfaktor mit Sieb:
quelle
Es scheint mir, dass Schritt 2 des angegebenen Algorithmus kein allzu effizienter Ansatz sein wird. Sie haben keine vernünftige Erwartung, dass es Prime ist.
Auch die vorherige Antwort, die das Sieb des Eratosthenes vorschlägt, ist völlig falsch. Ich habe gerade zwei Programme mit dem Faktor 123456789 geschrieben. Eines basierte auf dem Sieb, eines auf dem folgenden:
Diese Version war 90x schneller als das Sieb.
Die Sache ist, auf modernen Prozessoren ist die Art der Operation weitaus weniger wichtig als die Anzahl der Operationen, ganz zu schweigen davon, dass der obige Algorithmus im Cache ausgeführt werden kann, das Sieve nicht. Das Sieb verwendet viele Operationen, um alle zusammengesetzten Zahlen zu streichen.
Beachten Sie auch, dass meine Aufteilung der identifizierten Faktoren den zu testenden Speicherplatz verringert.
quelle
Berechnen Sie zuerst eine Liste, in der Primzahlen gespeichert sind, z. B. 2 3 5 7 11 13 ...
Verwenden Sie jedes Mal, wenn Sie eine Zahl mit Primzahlen faktorisieren, die Implementierung von Triptychon, wiederholen Sie jedoch diese Liste mit Primzahlen und nicht mit natürlichen ganzen Zahlen.
quelle
Mit Java:
Für
int
Werte:Für
long
Werte:quelle
Dies ist wahrscheinlich nicht immer schneller, aber optimistischer, wenn Sie einen großen Hauptteiler finden:
N
ist deine Nummerreturn(N)
Sqrt(N)
N is divisible by Prime
dannReturn(Prime)
Bearbeiten: In Schritt 3 können Sie das Sieb von Eratosthenes oder das Sieb von Atkins oder was auch immer Sie möchten verwenden, aber das Sieb allein wird Sie nicht als den größten Hauptfaktor finden. (Deshalb würde ich den Beitrag von SQLMenace nicht als offizielle Antwort wählen ...)
quelle
Ich denke, es wäre gut, alle möglichen Primzahlen, die kleiner als n sind, irgendwo zu speichern und sie einfach zu durchlaufen, um den größten Teiler zu finden. Sie können Primzahlen von prime-numbers.org erhalten .
Natürlich gehe ich davon aus, dass deine Nummer nicht zu groß ist :)
quelle
Nicht das schnellste, aber es funktioniert!
quelle
Hier ist die gleiche Funktion @ Triptychon als Generator vorgesehen, die ebenfalls leicht vereinfacht wurde.
Die maximale Primzahl kann dann ermittelt werden mit:
und eine Liste von Faktoren, die gefunden wurden mit:
quelle
quelle