簡體   English   中英

python中的質數生成代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM