J'essaie de trouver un algorithme efficace en Java pour trouver la partie décimale répétitive de deux entiers a
et b
où a/b
.
par exemple. 5/7 = 0,714258 714258 ....
Je ne connais actuellement que la méthode de la division longue.
algorithms
math
Jun Hao
la source
la source
Réponses:
Je crois qu'il y a deux approches générales ici, vous pouvez essentiellement rechercher par "force brute" la chaîne répétitive la plus longue, ou vous pouvez la résoudre comme un problème de théorie des nombres.
Cela fait longtemps que je n'ai pas rencontré ce problème, mais un cas spécial (1 / n) est le problème # 26 sur Project Euler, donc vous pourrez peut-être trouver plus d'informations en recherchant des solutions efficaces pour ce nom spécifique. Une recherche nous mène au site Web d'Eli Bendersky, où il explique sa solution . Voici une partie de la théorie de la page Expansion décimale de Mathworld :
Ma théorie des nombres est un peu rouillée pour le moment, donc le mieux que je puisse faire est de vous orienter dans cette direction.
la source
Laissez
n < d
, et vous essayez de comprendre la partie répétitive den/d
. Soitp
le nombre de chiffres dans la partie répétitive: alorsn/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...)
. La partie entre crochets est une série géométrique, égale à1/(10^p - 1)
.Alors
n / d = R / (10^p - 1)
. Réorganisez pour obtenirR = n * (10^p - 1) / d
. Pour trouver R, bouclezp
de 1 à l'infini et arrêtez dès que lad
division est égalen * (10^p - 1)
.Voici une implémentation en Python:
(
k
garde une trace de la longueur de la séquence répétée, afin que vous puissiez faire la distinction entre 1/9 et 1/99, par exemple)Notez que cette implémentation (ironiquement) boucle pour toujours si l'expansion décimale est finie, mais se termine si elle est infinie! Vous pouvez vérifier ce cas, car
n/d
il n'aura une représentation décimale finie que si tous les facteurs premiersd
qui ne sont pas 2 ou 5 sont également présents dansn
.la source
0.123123... = 123/999
0.714258714258... = 714258/999999 (=5/7)
etc.Division longue? : /
Transformez le résultat en chaîne, puis appliquez-lui cet algorithme . Utilisez BigDecimal si votre chaîne n'est pas assez longue avec des types ordinaires.
la source