演算法 素數篩法

2021-07-10 13:55:48 字數 1232 閱讀 5131

素數篩法是acm 及各大比賽中必須熟練掌握的最低階的演算法,在已知某些素數的情況下對未判斷的數進行篩選,篩選掉必然不是素數的數。如何對數進行篩選,依據素數的性質,某個除1以外的正整數是素數,則該數的倍數一定不是素數

從1-10中篩選出所有素數

步驟當前元素12

3456

78910

原始陣列//

0000

0000

0第一步2/

0010

1010

1第二步3/

0010

1011

1第三步5/

0010

1011

1第四步7/

0010

1011

1 以第一步為例:當前元素為2,則將2∗

2=4 ,2∗

3=6 ,2∗

5=10 都置為合數,即每次都將當前為素數的元素的倍數從候選的數中除去。

迴圈上述過程,則可得到最終的陣列,陣列中為0的則該元素為素數,否則為合數。

#include 

#define maxn 11

int prime[maxn] = ; //第0,1個元素直接設為合數,合數設為1,素數為0

int main() }}

return

0;}

該演算法的複雜度為o(

n2) ,但常係數非常小,實際執行時接近o(

n)複雜度,並且隨著篩選的進行,可以仔細思考一下,最後篩選掉的數越來越多,剩下的素數越來越小,即素數之間的間隔越來越大。

在素數篩法的過程中,有許多重複計算的過程可以進行優化,例如上述例子中,元素6和元素10都篩選了兩次,就是**中紅了兩次。

下邊列一下可以優化的點,就不具體實現了。

1. 避免重複篩選

2. 偶數直接可以不參與篩選,並且依據這個規則可以將陣列大小優化掉一半

說明一下第二點可以優化空間的方法,例如原陣列的第

i 個元素代表數字i是否為素數,若直接將偶數去除,則陣列的第

i個元素則可代表數字2∗

i−1 是否為素數。

想繼續學習素數有關知識的可以看看以下幾個知識點

費馬測試

miller-rabin 質數測試

尤拉-雅科比測試

aks質數測試

等等素性測試演算法,可能以後會在詳細討論這些演算法。

素數篩法(素數篩 線性篩)

求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...

演算法之素數篩法

1 方法一 判斷是否是乙個素數 int isprime int a 計算列舉上界,為防止double值帶來的精度損失,所以採用根號值取整後再加1,即寧願多列舉乙個,也不願少列舉乙個數 2 方法二 判斷是否是乙個素數 mark 標記陣列 index 素數個數 int prime else return...

演算法 素數的篩法

本文實現了素數的篩法演算法。在寫 的過程中,時不時會遇到求解素數的任務,特意將素數求解方法總結成文章以備不時之需。素數的求解演算法大概有兩種。一種是列舉某一範圍的數,然後逐個判斷該數是否為素數。這種方法簡單但效率不高。另一種方法是使用素數的篩法將某一範圍內的所有素數篩選出來,然後再打表。篩法的原理很...