素數篩法 - 歐拉篩法
素數的篩法有幾種,這次主要談一下歐拉篩法
1.暴力求素數
時間複雜度 : O(n2)
稍微優化一下 :縮小數據範圍從 n 優化到√n
時間複雜度 : 自然也就從 O(n2) 到 O(√n)
2.著名的埃式篩法
時間複雜度 : O(nloglogn)
而要談的歐拉篩法則是在埃式篩法的基礎上再次進行優化
3.歐拉篩法
時間複雜度爲: O(n)
#include<cstdio>
using namespace std;
int judge[10000]; //保存 這個數是否爲素數
int prime[10000]; //用來保存已經找到的素數
int count; //統計素數的個數
int main()
{
int n;
scanf("%d",&n);
for(int i = 2;i <= n;i++)
{
if(!judge[i]) //如果judge[i] 沒有被標記爲合數
{
prime[count] = i; //將 i 保存進數組
count++;
} //i*prime[j] 爲合數
for(int j = 0;j < count && i*prime[j] <= n;j++) //j 遍歷的 是 已保存 的 素數
{ //i*prime[j] 爲合數
judge[i*prime[j]] = 1; // 將 i*prime[j] 進行標記
if(i % prime[j] == 0) break; //如果 prime[j] 是 i 的最小質因子,跳出
}
}
printf("%d\n",count);
}
歐拉篩法 比 埃式篩法 的優化 :
歐拉篩法在埃式篩法的基礎上,讓每個合數只被它的最小質因子篩選一次,以達到不重複的目的。
質因子:在數論裏,某一正整數的質因子指能整除該數的質數整數。
if(i % prime[j] == 0) break; //和埃式篩法最大的不同 ,,避免了重複刪除
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 …
當 i 等於 4 時, 將 8 標記爲合數 在這之後 break,因爲繼續判斷的話會將 12 標記
當 i 等於 6 時, 會將 12 進行標記 ,重複標記造成浪費