Python “OverflowError”
Je commence tout juste à apprendre à coder en Python. Je suis en train d'écrire un peu de code pour répondre à ce Projet Euler Question:
Les facteurs premiers de 13195 sont 5, 7, 13 et 29.
Ce qui est le plus grand facteur premier de le nombre 600851475143 ?
Mon programme fonctionne avec les cas de test de 13195, mais quand j'essaie d'entrer 600851475143, j'obtiens l'erreur: "OverflowError: range() résultats a trop d'éléments"
Personne ne sait comment je peux résoudre ce problème?
Voici mon code:
class Euler3:
"A class to find the largest prime factor of a given number"
n = 600851475143
primeFactors = []
for i in range(2,n):
if (n%i ==0):
primeFactors.append(i)
n = n/i
i = i -1 #reset i
print primeFactors
Toute aide ou suggestion serait bien apprécié!
Vous le faites mal. Pour chaque facteur de
x
, il y a un autre facteur y
tels que x*y = num
. Si x
dans le n-ième plus petit facteur, y
sera le n-ième facteur le plus important (la preuve de ceci est un exercice laissé au lecteur). Trouver le plus petit facteur x
, et ne y = num/x
. Si y
est premier, c'est votre numéro, si non, continuez. Aussi, x
est sensiblement plus petit que sqrt(num)
, de sorte que vous pouvez réduire votre range()
un peu.OriginalL'auteur Erica Dohring | 2012-05-28
Vous devez vous connecter pour publier un commentaire.
La
range
fonction crée une liste et tente de le stocker dans la mémoire. Création d'une liste du nombre de numéros longtemps est la cause de la OverflowError. Vous pouvez utiliserxrange
au lieu d'obtenir un générateur qui produit l'un des numéros sur la demande.Cela dit, je pense que vous trouverez que votre algorithme est beaucoup trop lent pour le calcul de grands nombres premiers. Il y a beaucoup de nombre premier algorithmes, mais j'ai peut proposer de vérifier la Crible d'Eratosthène comme un point de départ.
EDIT: Correctement
xrange
ne fait pas de retour d'un générateur, mais un xrange objet qui se comporte un peu comme un générateur. Je ne sais pas si vous vous en souciez, mais il était sur écoute-moi que je n'étais pas précis!OriginalL'auteur
Je devine que vous êtes à l'aide de python 2 et pas de python 3 --
range(2,n)
effectivement construit une liste! Vous n'avez pas assez de mémoire pour stocker les 600 milliards de chiffres!xrange
devrait être bon, cependant.Aussi, votre idée de
i=i-1
ne fonctionne pas. Pour les boucles ne fonctionnent pas comme en C, et que le hack ne fonctionne que dans le style C boucles. La boucle for parcourtrange(2,n)
. Sii
obtient la valeur5
à la fois itération, alors peu importe ce que vous faites pouri
, il obtient toujours6
la prochaine fois.Aussi, la liste
range(2,n)
est construit lorsque vous entrez dans la boucle. Ainsi, lorsque vous modifiezn
, ça ne change rien.Vous allez avoir à repenser votre logique un peu.
(si vous ne me croyez pas, essayez d'utiliser 175 comme un cas de test)
Un dernier commentaire, vous devriez probablement obtenir dans l'habitude de l'aide de la division entière:
n = n //i
. Bien que/
et//
les mêmes en python 2, qui est vraiment obsolète de comportement, et ils ne travaillent pas de la même chose en python 3, où/
vous donnera un nombre à virgule flottante.OriginalL'auteur
Vous pouvez résoudre le problème en utilisant
xrange
au lieu derange
Votre prochain problème sera que le programme prend beaucoup trop de temps à s'exécuter parce que vous avez besoin de sortir de la boucle sous certaines condition
Une meilleure façon de traiter avec la répétition des facteurs est de remplacer le
if
avec unwhile
Je vais essayer ça. Merci!!!!
vous êtes la plupart de bienvenue
OriginalL'auteur
je pense que vous pouvez optimiser la fonction, en remarquant que
vous pouvez remplacer
par
car, vous pouvez voir wiki...
OriginalL'auteur
C'est la meilleure façon de trouver des nombres premiers que j'ai trouvé jusqu'à présent:
OriginalL'auteur
Ce qui m'a pris environ 5 secondes pour trouver la réponse.
OriginalL'auteur
xrange ne serez pas probablement vous aider(ou il peut!),mais la clé ici est de reliaze que vous n'avez pas besoin de trouver les nombres premiers jusqu'à 600851475143 ou les facteurs de 600851475143,mais c'est le premier des facteurs,donc...
Utiliser la bonne vieille méthode de factorisation ,comme suit:
Ce sera le retour de la argest premier facteur presque instantanément
OriginalL'auteur
J'ai été aux prises avec ce Python "OverflowError", ainsi, en travaillant sur ce projet. Il a été me rend fou en essayant de trouver une combinaison qui fonctionne.
Cependant, je n'ai découvert un d'intelligent, au moins je pense que oui :), la façon de le faire.
Voici mon code pour ce problème.
Ce que j'ai fait était de prendre les facteurs du nombre entré et entrez dans une liste des "facteurs". Après cela, je prends la liste de facteurs et de déterminer celles qui sont les nombres premiers et de les stocker dans une liste, qui est imprimé.
J'espère que cette aide
-- Mike
OriginalL'auteur