簡體   English   中英

Prime發生器(用於Spoj解決方案)

[英]Prime Generator(for Spoj solution)

我花了幾天的時間來解決這個SPOJ問題的Prime Generator算法。 問題狀態是在6秒鍾內從n <= 1000000000的數字m,n打印至少100000個素數。 我有這個實現在11.701067686080933秒內打印100000素數的實現。 是否有可能超過Python中的時間限制(6s)。 我感覺我錯過了細分篩函數中的某些內容,因為我只是通過理解算法的方式實現了它,也許進行更改可以使其變得更好。

一些幫助將不勝感激。

def sieveOfErosthen(m):
    limit=m+1
    prime=[True]*limit

    for i in range(2,int(m**0.5)):
        if prime[i]:
            for x in range(i*i,limit,i):
                prime[x]=False
    return prime  

def segmentedSieve(m,n):
    limit= n+1
    segment=[True]*limit

    for j in range(2,int(n**0.5) ):
        if sieveOfErosthen(j):
            for b in range(j*(m//j),limit,j):
                if b >j:
                    segment[b]=False
    for v in range(m,limit):
        if segment[v]:
            print(v)
    return True

此代碼是一場災難。 讓我們從最明顯的錯誤開始:

if sieveOfErosthen(j):

(這特別令人困惑,因為您的原始代碼未定義此函數,而是定義了EratosthenesSieve() -后來您的帖子編輯器將一個映射到另一個,我認為是正確的。) sieveOfErosthen(j)返回什么? 它返回一個數組,因此在if的布爾上下文中,此測試始終為True ,因為如果j為正,則該數組始終包含至少一個元素!

將其更改為if True:並查看您的輸出未更改。 剩下的是效率非常低下的篩分算法,我們可以通過多種方式加快它的速度:

def segmentedSieve(m, n):
    primes = []
    limit = n + 1
    segment = [True] * limit

    if limit > 0:
        segment[0] = False

        if limit > 1:
            segment[1] = False

    for j in range(2, int(limit**0.5) + 1):
        if segment[j]:
            for b in range(j * j, limit, j):
                segment[b] = False

    for v in range(m, limit):
        if segment[v]:
            primes.append(v)

    return primes

這段代碼可以很容易地在不到一秒的時間內找到前100,000個素數,但是最終,如果n <= 1000000000 (十億),則我們必須假設最壞的情況,即在6秒內對於某些合適的m輸入最后100,000個素數。 segmentedSieve(m, 1000000000)將花費此代碼分鍾而不是秒。

最終,您沒有實現分段篩子 ,而是實現了常規篩子,只是略過了請求的范圍。 我建議您在Wikipedia或其他地方閱讀有關分段篩的信息 ,如果需要分段篩,請重新開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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