一般篩法求素數 快速線性篩法求素數

2021-09-30 04:52:49 字數 1791 閱讀 1476

tag 素數  數論

素數總是乙個比較常涉及到的內容,掌握求素數的方法是一項基本功。

基本原則就是題目如果只需要判斷少量數字是否為素數,直接列舉因子2 。。n^(0.5) ,看看能否整除n。

如果需要判斷的次數較多,則先用下面介紹的辦法預處理。

首先先介紹一般的線性篩法求素數

void make_prime()  ,num_prime = 0;    

int isnotprime[n] = ;

int main()

}

return 0;

}

首先,先明確乙個條件,任何合數都能表示成一系列素數的積。

不管 i 是否是素數,都會執行到「關鍵處1」,

①如果 i 都是是素數的話,那簡單,乙個大的素數 i 乘以不大於 i 的素數,這樣篩除的數跟之前的是不會重複的。篩出的數都是 n=p1*p2的形式, p1,p2之間不相等

②如果 i 是合數,此時 i 可以表示成遞增素數相乘 i=p1*p2*...*pn, pi都是素數(2

<=i<=n),  pi<=pj  ( i<=j )

p1是最小的係數。

根據「關鍵處2」的定義,當p1==prime[j] 的時候,篩除就終止了,也就是說,只能篩出不大於p1的質數

*i。我們可以直觀地舉個例子。i=2*3*5

此時能篩除 2*i ,不能篩除 3*i

如果能篩除3*i 的話,當 i' 等於 i'=3*3*5 時,篩除2*i' 就和前面重複了。

乙個數會不會被重複篩除。

合數肯定會被乾掉。

根據上面紅字的條件,現在分析乙個數會不會被重複篩除。

設這個數為 x=p1*p2*...*pn, pi都是素數(1<=i<=n)  ,  pi<=pj ( i<=j )

當 i = 2 時,就是上面①的情況,

當 i >2 時, 就是上面②的情況, 對於 i ,第乙個能滿足篩除 x 的數  y 必然為 y=p2*p3...*pn(p2可以與p1相等或不等),而且滿足條件的 y 有且只有乙個。所以不會重複刪除。

證明合數肯定會被乾掉? 用歸納法吧。

模擬乙個模型,比如說我們要找出 n 中2個不同的數的所有組合 ,1<=i<=n, 1<=j<=n,

我們會這麼寫

for (i=1; ifor (j=i+1; j<=n; ++j)

我們取 j=i+1 便能保證組合不會重複。快速篩法大概也是這個道理,不過這裡比較難理解,沒那麼直觀。

1樓提供的方法,我整理下

//偶數顯然不行,所以先去掉偶數。可以看作上面第一種的優化吧。

//不過這種方法不太直觀,不太好理解。

我推薦這個演算法! 易於理解。 只算奇數部分,時空效率都還不錯!

half=size/2;

int sn = (int) sqrt(size);

for (i = 0; i < half; i++)

p[i] = true;// 初始化全部奇數為素數。p[0]對應3,即p[i]對應2*i+3

for (i = 0; i < sn; i++)

} //素數都存放在 p 陣列中,p[i]=true代表 i+i+2 是素數。

//舉例,3是素數,按3*3,3*5,3*7...的次序篩選,因為只儲存奇數,所以不用刪3*4,3*6....

列印質數的各種演算法   裡面有個用c++模板實現的,純屬開闊眼界,不怎麼實用。

檢查素數的正規表示式    數字n用  1111。。1 (n個1)表示,純屬坑爹。

一般篩法求素數 快速線性篩法求素數

素數總是乙個比較常涉及到的內容,掌握求素數的方法是一項基本功。基本原則就是題目如果只需要判斷少量數字是否為素數,直接列舉因子2 n 0.數 5 看看能否整除n。如果需要判斷的次數較多,則先用下面介紹的辦法預處理。首先先介紹一般的線性篩法求素數 void make prime num prime 0 ...

一般篩法求素數 快速線性篩法求素數

tag 素數 數論 素數總是乙個比較常涉及到的內容,掌握求素數的方法是一項基本功。基本原則就是題目如果只需要判斷少量數字是否為素數,直接列舉因子2 n 0.5 看看能否整除n。如果需要判斷的次數較多,則先用下面介紹的辦法預處理。首先先介紹一般的線性篩法求素數 void make prime num ...

一般篩法求素數 快速線性篩法求素數

素數總是乙個比較常涉及到的內容,掌握求素數的方法是一項基本功。基本原則就是題目如果只需要判斷少量數字是否為素數,直接列舉因子2 n 0.5 看看能否整除n。如果需要判斷的次數較多,則先用下面介紹的辦法預處理。首先先介紹一般的線性篩法求素數 cpp view plain copy void make ...