Ich versuche, einen effizienten Algorithmus in Java zu finden, um den sich wiederholenden Dezimalteil von zwei Ganzzahlen zu finden a
und b
wo a/b
.
z.B. 5/7 = 0,714258 714258 ....
Ich kenne derzeit nur die Methode der langen Teilung.
algorithms
math
Jun Hao
quelle
quelle
Antworten:
Ich glaube, dass es hier zwei allgemeine Ansätze gibt, Sie können im Wesentlichen "Brute Force" nach der längsten sich wiederholenden Zeichenfolge suchen oder Sie können es als ein Problem der Zahlentheorie lösen.
Es ist lange her, dass ich auf dieses Problem gestoßen bin, aber ein Sonderfall (1 / n) ist Problem Nr. 26 in Project Euler, sodass Sie möglicherweise mehr Informationen finden, indem Sie nach effizienten Lösungen für diesen bestimmten Namen suchen. Eine Suche führt uns zu Eli Benderskys Website, auf der er seine Lösung erklärt . Hier ist ein Teil der Theorie von Mathworlds Decimal Expansions-Seite :
Meine Zahlentheorie ist im Moment ein bisschen verrostet, also ist das Beste, was ich tun kann, Sie in diese Richtung zu lenken.
quelle
Lassen Sie
n < d
, und Sie versuchen, den sich wiederholenden Teil von herauszufindenn/d
. Seip
die Anzahl der Ziffern im Wiederholungsteil: dannn/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...)
. Das Klammerteil ist eine geometrische Reihe, gleich1/(10^p - 1)
.Also
n / d = R / (10^p - 1)
. Neu anordnen, um zu bekommenR = n * (10^p - 1) / d
. Um R zu finden, gehen Siep
von 1 bis unendlich und halten Sie an, sobald Sie sichd
gleichmäßig geteilt habenn * (10^p - 1)
.Hier ist eine Implementierung in Python:
(
k
Verfolgt die Länge der Wiederholungssequenz, sodass Sie beispielsweise zwischen 1/9 und 1/99 unterscheiden können.)Beachten Sie, dass diese Implementierung (ironischerweise) eine Endlosschleife ausführt, wenn die Dezimalerweiterung endlich ist, aber endet, wenn sie unendlich ist! Sie können diesen Fall jedoch überprüfen, da
n/d
nur dann eine endliche Dezimaldarstellungd
vorliegt, wenn alle Primfaktoren , die nicht 2 oder 5 sind, auch in vorhanden sindn
.quelle
0.123123... = 123/999
0.714258714258... = 714258/999999 (=5/7)
usw.Lange Trennung? : /
Verwandeln Sie das Ergebnis in eine Zeichenfolge und wenden Sie diesen Algorithmus darauf an. Verwenden Sie BigDecimal, wenn Ihre Zeichenfolge bei normalen Typen nicht lang genug ist.
quelle