Imprimer une série de nombres premiers en python
Je suis en train d'apprendre de programmation Python, et je suis assez nouveau à ce.
J'ai eu des problèmes à l'impression d'une série de nombres premiers de un à cent. Je ne peux pas déterminer quel est le problème avec mon code.
Voici ce que j'ai écrit; il imprime tous les nombres impairs au lieu de nombres premiers:
for num in range(1,101):
for i in range(2,num):
if (num%i==0):
break
else:
print(num)
break
source d'informationauteur user1546721 | 2012-07-23
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin de vérifier tous les nombres de 2 à n-1 (à sqrt(n) en fait, mais bon, que ce soit n).
Si
n
est divisible par aucun des nombres, il n'est pas premier. Si un nombre est premier, l'imprimer.Vous pouvez écrire la même beaucoup plus court et plus pythonic:
Comme je l'ai déjà dit, il serait préférable de vérifier les diviseurs pas de 2 à n-1, mais à partir de 2 à sqrt(n):
Pour les petits nombres comme 101 il n'a pas d'importance, mais pour 10**8 la différence sera vraiment gros.
Vous pouvez l'améliorer un peu plus par incrémentation de la plage vous de vérifier par 2, et donc la seule vérification des numéros impairs. Comme:
Édité:
break
termine la boucle qu'il est actuellement. Donc, vous n'êtes jamais vérifier si il divisible par 2, vous donnant tous les nombres impairs.cela étant dit, il ya beaucoup de meilleures façons de trouver des nombres premiers en python que cela.
Au lieu de la division de première instance, une meilleure approche, inventé par le mathématicien grec Eratosthène plus de deux mille ans, est à tamis à plusieurs reprises par le rejet des multiples de nombres premiers.
Commencez par faire une liste de tous les nombres de 2 au maximum désiré le premier n. Puis plusieurs reprises de prendre la plus petite décroise nombre et de la croix de l'ensemble de ses multiples; le nombre qui restent non barrés sont de qualité.
Par exemple, considérons les nombres inférieurs à 30. Initialement, 2 est identifié comme le premier, puis 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 et 30 sont croisés. 3 est identifié comme le premier, puis 6, 9, 12, 15, 18, 21, 24, 27 et 30 sont croisés. Le prochain premier est de 5, 10, 15, 20, 25 et 30 sont croisés. Et ainsi de suite. Le nombre qui restent sont le premier: 2, 3, 5, 7, 11, 13, 17, 19, 23, et 29.
Une version optimisée du tamis poignées 2 séparément et cribles seulement des nombres impairs. Aussi, puisque tous les composites de moins que la place de l'actuel premier sont traversés par de plus petits nombres premiers, la boucle interne peut commencer à p^2 au lieu de p et de la boucle externe peut s'arrêter à la racine carrée de n. Je vais laisser la version optimisée pour vous de travailler sur.
Je suis un promoteur de ne pas en supposant que la meilleure solution et de le tester. Ci-dessous sont quelques modifications que j'ai fait pour créer des classes d'exemples par les deux @igor-chubin et @user448810. Tout d'abord permettez-moi de dire que toutes les bonnes informations, merci les gars. Mais je dois reconnaître @user448810 pour sa solution intelligente, qui s'avère être le plus rapide, et de loin (de ceux que j'ai testé). Donc, bravo à vous, monsieur! Dans tous les exemples que j'ai utiliser une valeur de 1 million (1.000.000) de n.
N'hésitez pas à essayer le code.
Bonne chance!
Méthode 1 comme décrit par Igor Chubin:
Référence: 272+ secondes
Méthode 2 comme décrit par Igor Chubin:
Référence: 73.3420000076 secondes
Méthode 3 comme décrit par Igor Chubin:
Référence: 11.3580000401 secondes
Méthode 4 comme décrit par Igor Chubin:
Référence: 8.7009999752 secondes
Méthode 5 comme décrit par user448810 (j'ai pensé que c'était très habile):
Référence: 1.12000012398 secondes
Notes: Solution 5 énumérées ci-dessus (comme proposé par user448810) s'est avéré pour être le plus rapide et honnêtement calme, créative et intelligente. Je l'aime. Merci les gars!!
EDIT: Oh, et par la manière, je n'ai pas le sentiment qu'il était nécessaire d'importer la bibliothèque de mathématiques pour la racine carrée d'une valeur équivalente est juste (n**.5). Sinon, je n'ai pas modifier beaucoup d'autres ensuite rendre les valeurs sont enregistrées dans le et le tableau de sortie renvoyée par la classe. Aussi, il serait probablement un peu plus efficace pour stocker les résultats dans un fichier que verbeux et pourrait sauver beaucoup de mémoire, si c'était juste un à la fois, mais en coûterait un peu plus de temps en raison d'écritures sur le disque. Je pense qu'il y a toujours de la place pour l'amélioration, même si. J'espère donc que le code de sens que les gars.
La meilleure façon de résoudre le problème ci-dessus serait d'utiliser le "Miller Rabin Test de Primalité" de l'algorithme. Il utilise une approche probabiliste pour déterminer si un nombre est premier ou pas. Et c'est par loin le plus efficace algorithme que j'ai rencontré pour la même chose.
Le python de la mise en œuvre de la même est démontré ci-dessous:
Un Programme en Python module de fonction qui renvoie la 1 st N nombres premiers:
Ma façon de liste de nombres premiers d'un numéro d'entrée sans trop de tracas est à l'aide de la propriété que vous pouvez obtenir tout nombre qui n'est pas premier avec la somme des nombres premiers.
Donc, si vous divisez le numéro de l'entrée avec tous les nombres premiers inférieurs, et il n'est pas divisible par l'un d'eux, vous savez que vous avez un nombre premier.
Bien sûr, il ya toujours des façons plus rapides d'obtenir les nombres premiers, mais celui-ci exécute déjà très bien, surtout parce que vous n'êtes pas divisant le numéro de l'entrée par un nombre quelconque, mais seulement les nombres premiers de tous la voie à ce nombre.
Avec ce code, j'ai réussi sur mon ordinateur à la liste de tous les nombres premiers jusqu'à 100 000 en moins de 4 secondes.
Impression de n nombres premiers à l'aide de python:
Igor Chubin's réponse peut être améliorée. Lors de l'essai si X est premier, l'algorithme ne pas avoir à vérifier chaque numéro jusqu'à la racine carrée de X, il n'a qu'à vérifier les nombres premiers jusqu'à la sqrt(X). Ainsi, il peut être plus efficace si elle se réfère à la liste des nombres premiers qu'il crée. La fonction ci-dessous renvoie une liste de tous les nombres premiers dans le groupe b, ce qui est pratique comme une liste pour plusieurs raisons (par exemple, lorsque vous voulez savoir le nombre de nombres premiers < b). Par la seule vérification que les premiers, il permet de gagner du temps au plus grand nombre (à comparer à environ 10 000; la différence est frappante).
Voici un moyen simple et intuitif de la version de vérifier si c'est un premier dans une fonction RÉCURSIVE! 🙂 (Je l'ai fait comme un devoir à la maison pour un MIT de la classe)
En python, il fonctionne très rapidement jusqu'en 1900. SI vous essayez plus de 1900, vous aurez une intéressante erreur 🙂 (u, comme pour vérifier combien de numéros de votre ordinateur peut gérer?)
Bien sûr... si vous aimez les fonctions récursives, ce petit code peut être mis à niveau avec un dictionnaire d'augmenter considérablement ses performances, et d'éviter que l'erreur drôle.
Voici un simple Niveau 1 mise à niveau avec une MÉMOIRE de l'intégration:
Voici le resultat, où j'ai imprimé sur les 100 derniers nombres premiers trouvés.
Il y a 9594 nombres premiers, jusqu'à 100000
[99991, 99989, 99971, 99961, 99929, 99923, 99907, 99901, 99881, 99877, 99871, 99859, 99839, 99833, 99829, 99823, 99817, 99809, 99793, 99787, 99767, 99761, 99733, 99721, 99719, 99713, 99709, 99707, 99689, 99679, 99667, 99661, 99643, 99623, 99611, 99607, 99581, 99577, 99571, 99563, 99559, 99551, 99529, 99527, 99523, 99497, 99487, 99469, 99439, 99431, 99409, 99401, 99397, 99391, 99377, 99371, 99367, 99349, 99347, 99317, 99289, 99277, 99259, 99257, 99251, 99241, 99233, 99223, 99191, 99181, 99173, 99149, 99139, 99137, 99133, 99131, 99119, 99109, 99103, 99089, 99083, 99079, 99053, 99041, 99023, 99017, 99013, 98999, 98993, 98981, 98963, 98953, 98947, 98939, 98929, 98927, 98911, 98909, 98899, 98897] ...
A pris à votre ordinateur 0:00:40.871083 pour calculer
De sorte qu'Il a fallu 40 secondes pour mon ordinateur portable i7 de la calculer. 🙂
Vous êtes à la terminaison de la boucle trop tôt. Après avoir testé toutes les possibilités dans le corps de la boucle for, et de ne pas briser, alors le nombre est premier. Comme on n'est pas premier, il faut commencer par 2:
Dans une solution plus rapide vous essayez seulement de diviser par des nombres premiers qui sont plus petits ou égaux à la racine du nombre que vous testez. Ceci peut être réalisé en se souvenant de tous les nombres premiers vous avez déjà trouvé. En outre, vous n'avez qu'à tester nombres impairs (sauf 2). Vous pouvez mettre de l'algorithme qui en résulte dans un générateur de sorte que vous pouvez l'utiliser pour stocker des nombres premiers dans un conteneur ou tout simplement de les imprimer:
Comme vous pouvez le voir il n'est pas nécessaire de calculer la racine carrée, il est plus rapide de magasin de la place pour chaque nombre premier et comparer chaque diviseur de ce nombre.
Ceci est un exemple de programme que j'ai écrit pour vérifier si un nombre est premier ou pas.
À l'aide de la fonction filtre.
Comment à ce sujet? La lecture de toutes les suggestions que j'ai utilisé ceci:
Les nombres premiers jusqu'à 1000000
La manière la plus rapide & meilleure mise en œuvre de l'omission sur les nombres premiers:
Ici est une approche différente que les métiers de l'espace pour une recherche plus rapide de temps. Cela peut être plus rapide.
J'ai été inspiré par Igor et fait un bloc de code qui crée une liste:
Ajoutant à la accepté de répondre, la poursuite de l'optimisation peut être obtenue en utilisant une liste de stocker des nombres premiers et de les imprimer après génération.
Ici est la plus simple logique pour les débutants d'obtenir les nombres premiers:
Ajoutant ma propre version, juste pour montrer quelques itertools astuces v2.7: