埃式篩法 尤拉篩法

2021-10-04 12:50:07 字數 1421 閱讀 1661

埃氏篩法是通過從小到大篩去乙個已知素數的倍數進而實現篩選的。

假如我們想篩掉1~100間的所有合數,步驟如下:

①2是質數,篩掉所有2的倍數

②3是質數,篩掉所有3的倍數

③4不是質數,跳過

④5是質數,篩掉所有5的倍數

⑤6不是質數,跳過

⑥7是質數,篩掉所有7的倍數

⑦8不是質數,跳過

⑧9不是質數,跳過

⑨10不是質數,跳過

總結一下,要想篩掉1~100內的所有合數,我們只需要,找到sqrt(100)=10內的所有質數,即2、3、5、7,把幾個數的倍數刪掉即可,那麼剩下的數就都是質數了。

模板如下:

int st[n]

;void

get_primes

(int n)

}}

時間複雜度:o(nlogn)我們知道,埃氏篩法是把每個質數的倍數都刪掉,比如最上面的那張,6和12被質數2篩了一次,又被質數3篩了一次,這是不是有點多餘,尤拉篩就是保證每個合數是被最小質因子篩掉的,就如6和12被最小質因子2篩掉的,質數3不需要再篩6和12了。

模板如下:

int st[n]

,primes[n]

,cnt;

void

get_primes

(int n)

}}

這一步,很重要!if(i % primes[ j ] == 0) break;為什麼當 i % primes[j] == 0時跳出迴圈呢,解釋一下:當滿足 if 條件時,i 可以看成 primes[j] * 某個數,而 i * p[j+1] 可以看成 primes[j] * 某個數 * primes[j+1],且 p[j] 一定是< p[j+1] 的,而且,我們知道,尤拉篩是通過合數的最小質因子來篩的,而 i * primes[j+1] 這個合數一定是可以被primes[j] 這個更小的質數篩掉的,不需要通過來primes[j+1]篩掉,因為primes[j+1]不是最小的質因子。舉個例子:i=4時,如果我們在 i%primes[0] ==0 時不退出迴圈,那就會篩掉3 * 4 這個合數,而12這個合數,我們希望是通過2 * 6 = 12篩掉的,所以需要在i % primes[j] == 0 時就 break。

尤拉篩也稱線性篩,因為其時間複雜度是線性的,o(n)

因為尤拉篩相比埃氏篩,減少了重複篩去同乙個合數的次數,當然也就比埃氏篩要快啦。

埃氏篩法與尤拉篩法

給定整數n,請問n以內有多少個素數?摘自挑戰程式程式設計。要列舉n以內素數,可以用埃氏篩法。這是乙個與輾轉相除法一樣古老的演算法。首先,將2到n範圍內的所有整數寫下來。其中最小的數字2是素數。將表中所有2的倍數都劃去。表中剩餘的最小數字是3,它不能被更小的數整除,所以是素數。在將表中所有3的倍數都劃...

篩法 尤拉篩和埃式篩(詳細至極)

首先,篩法是一種用來判斷質數的方法,可以刷出乙個質數表,所以也叫刷表法。基本思想 乙個整數的1以上且為整數倍是乙個合數。我們可以從小到大列舉n以內的質數,對其不超過n的倍數進行標記,剩下未標記的數即為質數。基本寫法 for int i 2 i n i 這時,我們會驚奇地發現時間複雜度很高。下面我們開...

埃式篩法和尤拉篩判斷素數

一般要判斷是是否為素數,我們通常找出了1和它本身之外是否存在可以被它整除的數。接著對判斷可以進行優化,出去偶數,判斷的邊界設定為math.sqrt number 如 以輸入101 200之間的素數為例 public static void fun1 else flag true if flag 還有...