Eratosthenes篩法求素數
阿新 • • 發佈:2018-12-11
Eratosthenes篩法高效求素數
篩法的思想:對於不超過n的每個非負整數p,刪除2p,3p,4p,5p,…,當處理完所有數之後,還沒有被刪除的數就是素數 這是簡易版的篩法,也最好理解
for(int i=2;i<=n;i++)
for(int j=i*2;j<=n;j+=i)
vis[j]=false;
還可以繼續改進,為什麼呢?給定外層迴圈變數i,內層迴圈的次數n/i-1<n/i。迴圈的總次數小於2/n+3/n+…+n/n=O(n * log n)。這個結論來自尤拉1+1/2+1/3+…+1/n=O(n*log n)+y,其中尤拉函式y約等於0.577218
改進:內層迴圈不必從i*2開始,它已經在i=2時被篩掉了
#include<iostream> #include<cstring> #include<cmath> using namespace std; bool vis[9999]; void Eratosthenes() //Eratosthenes篩法 { for(int i=2;i<=9999;i++) //外層迴圈 for(int j=i*i;j<=9999;j+=i) //內層迴圈 vis[j]=false; } int main() { int temp,n; memset(vis,true,sizeof(vis)); //素數表初始化 Eratosthenes(); while(cin>>n) //輸入區間上限 { temp=0; for(int i=0;i<=n;i++) //素數表初始化 { if(temp%10==0&&temp!=0) { temp=0; cout<<endl; } if(vis[i]) { temp++; cout<<i<<" "; } } } return 0; }
素數定理:count(x)=x/ln x count(x)表示不超過x的素數個數,它和x/ln x比較接近,所以這個定理是可以用來求一個區間的素數個數的