J'essaie d'apprendre la programmation en Python et je suis assez novice dans ce domaine.
J'avais des problèmes pour imprimer une série de nombres premiers allant de un à cent. Je ne peux pas comprendre ce qui ne va pas avec mon code.
Voici ce que j'ai écrit. il affiche 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
Vous devez vérifier tous les nombres de 2 à n-1 (à sqrt (n) en fait, mais ok, soit n) . Si n
est divisible par l’un des nombres, il n’est pas premier. Si un nombre est premier, imprimez-le.
for num in range(2,101):
prime = True
for i in range(2,num):
if (num%i==0):
prime = False
if prime:
print num
Vous pouvez écrire le même beaucoup plus court et plus Pythonic:
for num in range(2,101):
if all(num%i!=0 for i in range(2,num)):
print num
Comme je l'ai déjà dit, il serait préférable de vérifier les diviseurs non pas de 2 à n-1, mais de 2 à sqrt (n):
import math
for num in range(2,101):
if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1)):
print num
Peu importe, comme 101, ce n'est pas grave, mais pour 10 ** 8, la différence sera vraiment énorme.
Vous pouvez l’améliorer un peu plus en incrémentant de 2 la plage que vous vérifiez, et en vérifiant uniquement les nombres impairs. Ainsi:
import math
print 2
for num in range(3,101,2):
if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1)):
print num
Édité:
Comme dans la première boucle, des nombres impairs sont sélectionnés, dans la deuxième boucle, n ° __. besoin de vérifier avec des nombres pairs, donc la valeur 'i' peut être commencer par 3 et sauté par 2.
import math
print 2
for num in range(3,101,2):
if all(num%i!=0 for i in range(3,int(math.sqrt(num))+1, 2)):
print num
break
termine la boucle dans laquelle elle se trouve actuellement. Vous ne vérifiez donc que si elle est divisible par 2, ce qui vous donne tous les nombres impairs.
for num in range(2,101):
for i in range(2,num):
if (num%i==0):
break
else:
print(num)
cela dit, il existe de bien meilleurs moyens de trouver des nombres premiers en python que cela.
for num in range(2,101):
if is_prime(num):
print(num)
def is_prime(n):
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
Au lieu de la division d'essai, une meilleure approche, inventée par le mathématicien grec Eratosthenes il y a plus de deux mille ans, consiste à tamiser en jetant à plusieurs reprises des multiples de nombres premiers.
Commencez par faire une liste de tous les nombres allant de 2 au nombre premier souhaité n. Puis, à plusieurs reprises, prenez le plus petit nombre non croisé et rayez tous ses multiples; les nombres qui restent non croisés sont premiers.
Par exemple, considérons les nombres inférieurs à 30. Initialement, 2 est identifié comme premier, puis 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 et 30 sont rayés. Suivant 3 est identifié comme premier, puis 6, 9, 12, 15, 18, 21, 24, 27 et 30 sont rayés. Le nombre premier suivant est 5, donc 10, 15, 20, 25 et 30 sont rayés. Etc. Les nombres qui restent sont premiers: 2, 3, 5, 7, 11, 13, 17, 19, 23 et 29.
def primes(n):
sieve = [True] * (n+1)
for p in range(2, n+1):
if (sieve[p]):
print p
for i in range(p, n+1, p):
sieve[i] = False
Une version optimisée du tamis en traite 2 séparément et ne tamise que les nombres impairs. De plus, puisque tous les composites inférieurs au carré du nombre premier actuel sont barrés par des nombres premiers plus petits, la boucle interne peut commencer à p ^ 2 au lieu de p et la boucle externe peut s’arrêter à la racine carrée de n. Je laisserai la version optimisée sur laquelle vous pourrez travailler.
Je suis un partisan de ne pas assumer la meilleure solution et de la tester. Vous trouverez ci-dessous quelques modifications que j'ai apportées pour créer des classes simples d'exemples à la fois par @ igor-chubin et par @ user448810. Tout d’abord laissez-moi vous dire que c’est une excellente information, merci les gars. Mais je dois reconnaître @ user448810 pour sa solution intelligente, qui s'avère être de loin la plus rapide (parmi celles que j'ai testées). Alors bravo à vous, monsieur! Dans tous les exemples, j'utilise une valeur de 1 million (1 000 000) comme n.
S'il vous plaît n'hésitez pas à essayer le code.
Bonne chance!
Méthode 1 décrite par Igor Chubin:
def primes_method1(n):
out = list()
for num in range(1, n+1):
prime = True
for i in range(2, num):
if (num % i == 0):
prime = False
if prime:
out.append(num)
return out
Benchmark: Plus de 272 secondes
Méthode 2 décrite par Igor Chubin:
def primes_method2(n):
out = list()
for num in range(1, n+1):
if all(num % i != 0 for i in range(2, num)):
out.append(num)
return out
Indice de référence: 73.3420000076 secondes
Méthode 3 décrite par Igor Chubin:
def primes_method3(n):
out = list()
for num in range(1, n+1):
if all(num % i != 0 for i in range(2, int(num**.5 ) + 1)):
out.append(num)
return out
Indice de référence: 11,3580000401 secondes
Méthode 4 telle que décrite par Igor Chubin:
def primes_method4(n):
out = list()
out.append(2)
for num in range(3, n+1, 2):
if all(num % i != 0 for i in range(2, int(num**.5 ) + 1)):
out.append(num)
return out
Indice de référence: 8.7009999752 secondes
Méthode 5 comme décrit par user448810 (que j'ai trouvé assez intelligent):
def primes_method5(n):
out = list()
sieve = [True] * (n+1)
for p in range(2, n+1):
if (sieve[p]):
out.append(p)
for i in range(p, n+1, p):
sieve[i] = False
return out
Indice de référence: 1.12000012398 secondes
Notes: La solution 5 énumérée ci-dessus (telle que proposée par l'utilisateur448810) s'est avérée être la solution la plus rapide et la plus honnête qui soit, à la fois silencieuse et créative. J'aime cela. Merci les gars!!
EDIT: Oh, et d'ailleurs, je ne pensais pas qu'il était nécessaire d'importer la bibliothèque mathématique pour la racine carrée d'une valeur car l'équivalent est juste (n **. 5). Sinon, je n'ai pas beaucoup édité, puis les valeurs sont stockées et le tableau en sortie est renvoyé par la classe. En outre, il serait probablement un peu plus efficace de stocker les résultats dans un fichier que verbeux et d'économiser beaucoup de mémoire si cela ne se produit que l'un après l'autre, mais cela coûterait un peu plus de temps en raison des écritures sur disque. Je pense cependant qu'il y a toujours place à l'amélioration. J'espère donc que le code a du sens pour les gars.
Un module de fonction du programme Python qui renvoie les 1'st N nombres premiers:
def get_primes(count):
"""
Return the 1st count prime integers.
"""
result = []
x=2
while len(result) in range(count):
i=2
flag=0
for i in range(2,x):
if x%i == 0:
flag+=1
break
i=i+1
if flag == 0:
result.append(x)
x+=1
pass
return result
Le meilleur moyen de résoudre le problème ci-dessus serait d'utiliser l'algorithme "Miller Rabin Primality Test". Il utilise une approche probabiliste pour déterminer si un nombre est premier ou non. Et c'est de loin l'algorithme le plus efficace que j'ai rencontré pour la même chose.
L'implémentation de la même chose en python est illustrée ci-dessous:
def miller_rabin(n, k):
# Implementation uses the Miller-Rabin Primality Test
# The optimal number of rounds for this test is 40
# See http://stackoverflow.com/questions/6325576/how-many-iterations-of-rabin-miller-should-i-use-for-cryptographic-safe-primes
# for justification
# If number is even, it's a composite number
if n == 2:
return True
if n % 2 == 0:
return False
r, s = 0, n - 1
while s % 2 == 0:
r += 1
s //= 2
for _ in xrange(k):
a = random.randrange(2, n - 1)
x = pow(a, s, n)
if x == 1 or x == n - 1:
continue
for _ in xrange(r - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
Ma façon d’énumérer les nombres premiers avec un nombre sans trop de soucis consiste à utiliser la propriété suivante: vous pouvez obtenir n’importe quel nombre qui n’est pas un nombre premier avec la somme des nombres premiers.
Par conséquent, si vous divisez le nombre saisi avec tous les nombres premiers en dessous et qu'il n'est pas divisible par aucun d'entre eux, vous savez que vous avez un nombre premier.
Bien sûr, il existe encore des moyens plus rapides d’obtenir les nombres premiers, mais celui-ci fonctionne déjà très bien, en particulier parce que vous ne divisez pas le nombre saisi par un nombre, mais uniquement les nombres premiers jusqu’à ce nombre.
Avec ce code, j'ai réussi à répertorier tous les nombres premiers allant jusqu'à 100 000 en moins de 4 secondes sur mon ordinateur.
import time as t
start = t.clock()
primes = [2,3,5,7]
for num in xrange(3,100000,2):
if all(num%x != 0 for x in primes):
primes.append(num)
print primes
print t.clock() - start
print sum(primes)
min=int(input("min:"))
max=int(input("max:"))
for num in range(min,max):
for x in range(2,num):
if(num%x==0 and num!=1):
break
else:
print(num,"is prime")
break
a=int(input('enter the lower no.'))
b=int(input('enter the higher no.'))
print("Prime numbers between",a,"and",b,"are:")
for num in range(a,b):
if num>1:
for i in range(2,num):
if (num%i)==0:
break
else:
print(num)
Voici une version simple et intuitive permettant de vérifier s’il s’agit d’un élément principal dans une fonction RÉCURSIVE! :) (Je l'ai fait comme devoir pour une classe MIT) En python, il tourne très vite jusqu'en 1900. SI vous essayez plus que 1900, vous obtiendrez une erreur intéressante :) voudrais vérifier combien de numéros votre ordinateur peut gérer?)
def is_prime(n, div=2):
if div> n/2.0: return True
if n% div == 0:
return False
else:
div+=1
return is_prime(n,div)
#The program:
until = 1000
for i in range(until):
if is_prime(i):
print i
Bien sûr ... si vous aimez les fonctions récursives, ce petit code peut être mis à niveau avec un dictionnaire pour augmenter considérablement ses performances et éviter cette erreur amusante .Voici une simple mise à niveau de niveau 1 avec une intégration MEMORY:
import datetime
def is_prime(n, div=2):
global primelist
if div> n/2.0: return True
if div < primelist[0]:
div = primelist[0]
for x in primelist:
if x ==0 or x==1: continue
if n % x == 0:
return False
if n% div == 0:
return False
else:
div+=1
return is_prime(n,div)
now = datetime.datetime.now()
print 'time and date:',now
until = 100000
primelist=[]
for i in range(until):
if is_prime(i):
primelist.insert(0,i)
print "There are", len(primelist),"prime numbers, until", until
print primelist[0:100], "..."
finish = datetime.datetime.now()
print "It took your computer", finish - now , " to calculate it"
Voici les résultats, où j’ai imprimé les 100 derniers nombres premiers trouvés.
heure et date: 2013-10-15 13: 32: 11.674448
Il y a 9594 nombres premiers, jusqu'à 100000
[99991, 99989, 99971, 99961, 99929, 99923, 99907, 99901, 99881, 99877, 99871, 99859, 99839, 99833, 99829, 99817, 99817, 99793, 99793, 99767, 99767, 99767, 99767, 99767, 99767, 99767, 99767, 99767, 99767, 99767, 99767, 99767, 99733 99713, 99709, 99707, 99689, 99679, 99679, 99667, 99661, 99551, 99551, 99559, 99457, 99457, 99457, 99499, 9945, 99457, 99457, 99457, 9945, 99409, 99401 9939, 99391, 99371 99391, 99371, 99371, 99371, 99257, 99131, 99141, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131, 99131 99131, 99111, 99113, 99113, 99903, 98993, 98993, 98993, 98993, 98993, 98993, 98993, 98993, 98993, 9999 ] ...
Il a fallu à votre ordinateur 0: 00: 40.871083 pour le calculer
Il a donc fallu 40 secondes à mon ordinateur portable i7 pour le calculer. :)
n = int(raw_input('Enter the integer range to find prime no :'))
p = 2
while p<n:
i = p
cnt = 0
while i>1:
if p%i == 0:
cnt+=1
i-=1
if cnt == 1:
print "%s is Prime Number"%p
else:
print "%s is Not Prime Number"%p
p+=1
Voici la logique la plus simple pour les débutants d'obtenir des nombres premiers:
p=[]
for n in range(2,50):
for k in range(2,50):
if n%k ==0 and n !=k:
break
else:
for t in p:
if n%t ==0:
break
else:
p.append(n)
print p
C'est un exemple de programme que j'ai écrit pour vérifier si un nombre est premier ou non.
def is_prime(x):
y=0
if x<=1:
return False
Elif x == 2:
return True
Elif x%2==0:
return False
else:
root = int(x**.5)+2
for i in xrange (2,root):
if x%i==0:
return False
y=1
if y==0:
return True
Que dis-tu de ça? En lisant toutes les suggestions, j'ai utilisé ceci:
prime=[2]+[num for num in xrange(3,m+1,2) if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1))]
Nombres premiers jusqu'à 1000000
root@nfs:/pywork# time python prime.py
78498
real 0m6.600s
utilisateur 0m6.532s
sys 0m0.036s
def prime_number(a):
yes=[]
for i in range (2,100):
if (i==2 or i==3 or i==5 or i==7) or (i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0 and i%(i**(float(0.5)))!=0):
yes=yes+[i]
print (yes)
def fac(n):
res = []
for i in range(1,n+1):
if n%i == 0:
res.append(i)
def prime(n):
return(fac(n) == [1,n])
def prime_list(n):
pri_list = []
for i in range(1,n+1):
if prime(i)
pri_list.append(i)
return(pri_list)
f=0
sum=0
for i in range(1,101):
for j in range(1,i+1):
if(i%j==0):
f=f+1
if(f==2):
sum=sum+i
print i
f=0
print sum
L'implémentation la plus rapide et la meilleure d'omettre les nombres premiers:
def PrimeRanges2(a, b):
arr = range(a, b+1)
up = int(math.sqrt(b)) + 1
for d in range(2, up):
arr = omit_multi(arr, d)
Igor Chubin la réponse de/peut être améliorée. Lorsqu'il teste si X est premier, l'algorithme n'a pas à vérifier chaque nombre jusqu'à la racine carrée de X, il doit seulement vérifier les nombres premiers jusqu'au carré (X). Ainsi, il peut être plus efficace s’il se réfère à la liste des nombres premiers au fur et à mesure de sa création. La fonction ci-dessous génère une liste de tous les nombres premiers sous b, ce qui est pratique sous forme de liste pour plusieurs raisons (par exemple, lorsque vous souhaitez connaître le nombre de nombres premiers <b). En vérifiant uniquement les nombres premiers, vous gagnez du temps avec des nombres plus élevés (comparez autour de 10 000; la différence est frappante).
from math import sqrt
def lp(b)
primes = [2]
for c in range(3,b):
e = round(sqrt(c)) + 1
for d in primes:
if d <= e and c%d == 0:
break
else:
primes.extend([c])
return primes
En plus de la réponse acceptée, une optimisation supplémentaire peut être obtenue en utilisant une liste pour stocker les nombres premiers et en les imprimant après la génération.
import math
Primes_Upto = 101
Primes = [2]
for num in range(3,Primes_Upto,2):
if all(num%i!=0 for i in Primes):
Primes.append(num)
for i in Primes:
print i
# computes first n prime numbers
def primes(n=1):
from math import sqrt
count = 1
plist = [2]
c = 3
if n <= 0 :
return "Error : integer n not >= 0"
while (count <= n - 1): # n - 1 since 2 is already in plist
pivot = int(sqrt(c))
for i in plist:
if i > pivot : # check for primae factors 'till sqrt c
count+= 1
plist.append(c)
break
Elif c % i == 0 :
break # not prime, no need to iterate anymore
else :
continue
c += 2 # skipping even numbers
return plist
Vous terminez la boucle trop tôt. Une fois que vous avez testé toutes les possibilités dans le corps de la boucle for, et que vous n’avez pas rompu, le nombre est premier. Comme on n’est pas premier, il faut commencer à 2:
for num in xrange(2, 101):
for i in range(2,num):
if not num % i:
break
else:
print num
Dans une solution plus rapide, essayez uniquement de diviser par des nombres premiers inférieurs ou égaux à la racine du nombre que vous testez. Cela peut être réalisé en se souvenant de tous les nombres premiers que vous avez déjà trouvés. De plus, il vous suffit de tester les nombres impairs (sauf 2). Vous pouvez placer l'algorithme résultant dans un générateur afin de pouvoir l'utiliser pour stocker des nombres premiers dans un conteneur ou simplement les imprimer:
def primes(limit):
if limit > 1:
primes_found = [(2, 4)]
yield 2
for n in xrange(3, limit + 1, 2):
for p, ps in primes_found:
if ps > n:
primes_found.append((n, n * n))
yield n
break
else:
if not n % p:
break
for i in primes(101):
print i
Comme vous pouvez le constater, il n’est pas nécessaire de calculer la racine carrée, il est plus rapide de stocker le carré pour chaque nombre premier et de comparer chaque diviseur avec ce nombre.
Voici une approche différente qui échange de l'espace pour un temps de recherche plus rapide. Cela peut être le plus rapide alors.
import math
def primes(n):
if n < 2:
return []
numbers = [0]*(n+1)
primes = [2]
# Mark all odd numbers as maybe prime, leave evens marked composite.
for i in xrange(3, n+1, 2):
numbers[i] = 1
sqn = int(math.sqrt(n))
# Starting with 3, look at each odd number.
for i in xrange(3, len(numbers), 2):
# Skip if composite.
if numbers[i] == 0:
continue
# Number is prime. Would have been marked as composite if there were
# any smaller prime factors already examined.
primes.append(i)
if i > sqn:
# All remaining odd numbers not marked composite must be prime.
primes.extend([i for i in xrange(i+2, len(numbers), 2)
if numbers[i]])
break
# Mark all multiples of the prime as composite. Check odd multiples.
for r in xrange(i*i, len(numbers), i*2):
numbers[r] = 0
return primes
n = 1000000
p = primes(n)
print "Found", len(p), "primes <=", n
Utilisation de la fonction de filtrage.
l=range(1,101)
for i in range(2,10): # for i in range(x,y), here y should be around or <= sqrt(101)
l = filter(lambda x: x==i or x%i, l)
print l
for num in range(1,101):
prime = True
for i in range(2,num/2):
if (num%i==0):
prime = False
if prime:
print num
J'ai été inspiré par Igor et j'ai créé un bloc de code qui crée une liste:
def prime_number():
for num in range(2, 101):
prime = True
for i in range(2, num):
if (num % i == 0):
prime = False
if prime and num not in num_list:
num_list.append(num)
else:
pass
return num_list
num_list = []
prime_number()
print(num_list)
Un moyen plus simple et plus efficace de résoudre ce problème consiste à stocker tous les nombres premiers trouvés précédemment et à vérifier si le nombre suivant est un multiple de l'un des plus petits nombres premiers.
n = 1000
primes = [2]
for i in range(3, n, 2):
if not any(i % prime == 0 for prime in primes):
primes.append(i)
print(primes)
Notez que any
est une fonction de court-circuit. En d’autres termes, elle cassera la boucle dès qu’une valeur de vérité sera trouvée.
Imprimer n nombres premiers en python:
num = input('get the value:')
for i in range(2,num+1):
count = 0
for j in range(2,i):
if i%j != 0:
count += 1
if count == i-2:
print i,