Ich mache eine Sieve of Eratosthenes-Implementierung in Python. Ein Problem, das auftritt, ist, dass nicht alle Primzahlen auftreten (hauptsächlich die mit der niedrigeren Nummer).
Hier ist mein Code:
def prevPrimes(n):
from math import sqrt
from time import time
start = time()
if type(n) != int and type(n) != long:
raise TypeError("Arg (n) must be of <type 'int'> or <type 'long'>")
if n <= 2:
raise ValueError("Arg (n) must be at least 2")
limit, x, num, primes = sqrt(n), 2, {}, []
for i in range(1, n+1):
num[i] = True
while x < limit:
for i in num:
if i%x==0:
num[i] = False
x += 1
for i in num:
if num[i]:
primes.append(i)
end = time()
primes = sorted(primes)
print round((end - start), 2), ' seconds'
return primes
Wenn ich >>> prevPrimes(1000)
eingebe, würde ich erwarten, dass das Ergebnis wie folgt beginnt: [2, 3, 5, 7, 11, 13, 17]
usw. So sieht es jedoch aus: [1, 37, 41, 43, 47, #more numbers]
.
Ich weiß, dass das Problem in der Tatsache liegt, dass die "ursprünglichen" Primzahlen (2, 3, 5, 7, 11, 13, 17 usw.) aufgrund der Art und Weise, wie mein Programm prüft, als False
angegeben werden die Primzahlen. Wie kann ich das vermeiden? Danke im Voraus :)
4 Antworten
Das war also keine tatsächliche SoE-Implementierung, eine, die ich vor einiger Zeit geschrieben habe, ist unten aufgeführt.
number_primes = 10
prime_list = [True]*number_primes
for i in range (2, number_primes): #check from 2 upwards
if prime_list[i]: #If not prime, don't need to bother about searching
j = 2
while j*i < number_primes: # Filter out all factors of i (2...n * prime)
prime_list[j*i] = False
j+=1
Zunächst die Antwort auf Ihre spezifische Frage. Sie verwerfen die Primzahlen, die kleiner als die Quadratwurzel von n sind. Die einfachste Lösung besteht darin, die Zeile num[i] = False
am Ende Ihrer inneren Schleife in num[i] = (not x == i)
zu ändern (ich denke, das funktioniert, ich habe es nicht getestet).
Zweitens ist Ihr Algorithmus eine Versuchsteilung, nicht das Sieb von Eratosthenes, und hat die Zeitkomplexität O (n ^ 2) anstelle von O (n log log n). Der Modulo-Operator verschenkt das Spiel. Das einfachste Sieb von Eratosthenes sieht so aus (Pseudocode, den Sie in Python übersetzen können):
function primes(n)
sieve := makeArray(2..n, True)
for p from 2 to n step 1
output p
for i from p+p to n step p
sieve[i] := False
Es gibt Möglichkeiten, diesen Algorithmus zu verbessern. Wenn Sie an der Programmierung mit Primzahlen interessiert sind, empfehle ich diesen Aufsatz , der ein optimiertes Eratosthenes-Sieb enthält, in bescheidenem Umfang Implementierung in Python.
Wenn Sie durch num
iterieren, ist x
manchmal gleich i
, sodass i % x
gleich 0 ist und i
als Nicht-Primzahl markiert wird.
Sie müssen if not x == i:
irgendwo in Ihrer while-Schleife hinzufügen, z.
while x < limit:
for i in num:
if not x == i:
if num[i] and i%x==0:
num[i] = False
Importzeit
Def primes_sieve1 ():
limitn = int(raw_input("Please enter an upper limit ")) +1
start = time.clock()
primes = {
}
for i in range(2, limitn):
primes[i] = True
for i in primes:
factors = range(i,limitn, i)
for f in factors[1:]:
primes[f] = False
end = time.clock()
print "This took ",end-start," seconds"
return [i for i in primes if primes[i]==True]
Primes_sieve1 ()
Anstatt Division zu verwenden, nimmt dieser Code die Vielfachen aller Zahlen, die kleiner als die Wurzel des Grenzwerts sind, und ändert sie in false. Dies ist etwas schneller, da nicht jede Zahl durch eine andere Zahl geteilt wird.
Auch unter 1000 tritt die Situation auf, dass eine Primzahl von selbst moduliert wird, um 0 zu ergeben, und das Programm dies für falsch hält. Da der sqrt (1000) ungefähr 31 beträgt, sind Primzahlen unter 31 betroffen.
Zum Beispiel tritt in der 7. Schleife von "while x
Verwandte Fragen
Neue Fragen
python
Python ist eine dynamisch typisierte Mehrzweck-Programmiersprache mit mehreren Paradigmen. Es wurde entwickelt, um schnell zu lernen, zu verstehen, zu verwenden und eine saubere und einheitliche Syntax durchzusetzen. Bitte beachten Sie, dass Python 2 ab dem 01.01.2020 offiziell nicht mehr unterstützt wird. Fügen Sie für versionenspezifische Python-Fragen das Tag [python-2.7] oder [python-3.x] hinzu. Wenn Sie eine Python-Variante (z. B. Jython, PyPy) oder eine Bibliothek (z. B. Pandas und NumPy) verwenden, fügen Sie diese bitte in die Tags ein.