厄拉多塞篩法和普通方法求素數表(python實現)


厄拉多賽篩法(sieve of Eratosthenes):


 

    想要得到一個不大於N的數所有素數,可以先找到不超過根號N的所有素數,設2 = p< p< ......<pk ≤√N,然后在2,3,4......N里面進行下面的操作:

    留下p= 2,把p1的倍數全部划掉,

    再留下p2 ,把p2 的倍數全部划掉,

    繼續這一過程,直到留下pk,把pk的倍數全部划掉,

    最后留下來就是不超過N的全體素數。

舉例:


 

N = 30   ,則取pk 為5,所以2到5的所有素數為2,3,5

第一遍 留下2,划去2的所有倍數

     2   3    4   5   6   7   8   9 10

11 12 13 14 15 16 17 18 19 20

21 22 23 24 25 26 27 28 29 30

第二遍 留下3,划去3的所有倍數

     2   3    4   5   6   7     9 10

11 12 13 14 15 16 17 18 19 20

21 22 23 24 25 26 27 28 29 30

第三遍 留下5,划去5的所有倍數

     2   3      5     7   8   9 10

11 12 13 14 15 16 17 18 19 20

21 22 23 24 25 26 27 28 29 30

剩余的數就是小於等於30的所有素數,即 2,3,5,7,11,13,17,19,23,29

算法實現:


 

算法思想來自於上面的介紹,但是並不是嚴格遵循上面的步驟:

def eladuosai(n):
    l = list(range(1,n+1))
    l[0] = 0
    for i in range(2,n+1):
        if l[i-1] != 0 :
            for j in range(i*2,n+1,i):
                l[j-1] = 0
    result = [x for x in l if x != 0]
    return result

 

求小於等於N的所有素數的普通算法:

def sushu(n):
    result = []
    for x in range(2,n+1):
        for y in range(2,x):
            if x % y == 0:
                break
        else:
            result.append(x)
    return result    

時間對比,使用timeit模塊測試兩個方法的時間,當取n為10000的時候有如下結論:

    t1 = timeit.Timer('sushu(10000)',setup='from __main__ import sushu')
    t2 = timeit.Timer('eladuosai(10000)',setup='from __main__ import eladuosai')
    print('厄拉多塞篩法的時間 ',t2.timeit(1))
    print('普通函數的時間 : ',t1.timeit(1))

厄拉多塞篩法的時間 0.005523548190824634
普通方法的時間 : 0.7220688150193577

 

 可以看出厄拉多塞篩法的運行時間比普通方法的時間要少很多。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM