[英]prime number generation code in python
我正在嘗試以下方法來生成素數:
primes = [2]
candidate = 3
MILLION = 1000000
while candidate < MILLION:
if all(candidate % prime for prime in primes if prime**2 <= candidate):
primes.append(candidate)
candidate += 2
但是,這比我以前的代碼要慢得多,在我以前的代碼中我沒有使用all
函數,而是自己進行檢查,如下所示:
primes = [2]
candidate = 3
MILLION = 1000000
while candidate < MILLION:
can_be_prime = True
for p in primes:
if p**2 > candidate:
break
elif candidate % p == 0:
can_be_prime = False
break
if can_be_prime:
primes.append(candidate)
candidate += 2
當第二個在10秒內結束時,第一個要花很長時間才能完成。 有人可以幫助我理解為什么第一個數字在第一個100000個數字之后開始如此緩慢地輸出嗎?
當你的想法,使用發電機表達縮短了代碼和any
好,他們是不等價的。 特別是,在較長的解決方案中,您要迭代素數的(排序的)列表,並在找到p ** 2 > candidate
為真的素數后立即中斷迭代。
但是,在生成器表達式中, x for p in primes if p ** 2 <= candidate
,則嘗試使用x for p in primes if p ** 2 <= candidate
進行此檢查。 不幸的是,這是不一樣的。 即使檢查失敗,發電機仍會繼續遍歷剩下的素數,執行的是p ** 2
每單質,在外部的每次迭代 while
循環。
如果您編寫的方式有所不同,則可以驗證這是問題所在:
def getPrimes (candidate):
for p in primes:
if p ** 2 > candidate:
break
yield p
while candidate < MILLION:
if all(candidate % prime for prime in getPrimes(candidate)):
primes.append(candidate)
candidate += 2
因此,現在,我們在較長版本中使用相同的想法,並在達到p ** 2 > candidate
為真的primes
終止primes
的迭代。 這樣,我們可以從更長的解決方案中獲得更快的速度。
我們實際上可以使用6n +/- 1
規則生成素數。 例如,如果要生成給定數字的質數:
def primes(N):
if N == 2:
primes = [2]
elif N >= 3:
primes = [2, 3]
else:
return None
for i in range(6, N):
if i % 6 == 0:
left = i - 1
right = i + 1
if all(left % p != 0 for p in primes):
primes.append(left)
if all(right % p != 0 for p in primes):
primes.append(right)
return primes
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.