Eratosthenes篩法(素數篩)

最一般的素數篩思想很簡單,對於不超過maxx的每個非負整數p,刪除2p,3p,4p,……,然後剩下的就是素數,複雜度O(nlogn),因爲對內層循環n/2+n/3+......+n/n  小於  1+1/2+1/3+...+1/n=ln(n+1)+γ,其中γ爲歐拉常數≈0.577218

應當注意,1不是素數哦~

這樣已經不慢,但由於所有非素數都能由素數與素數的乘積表示,又可以優化如下

int maxx=1000000;
long long prime[maxx];
bool isPrime[maxx];
void Eratosthenes()
{
    memset(isPrime,1,sizeof(isPrime));
    isPrime[1]=0;
    for(int i=2;i<=maxx;++i)
    {
        if(isPrime[i])
        {
            for(int j=2*i;j<=maxx;j+=i)
                isPrime[j]=0;
        }
    }
}


時間複雜度是O(nloglogn)

但是還能再優化,內層循環不必從i*2開始,它已經在i=2時候就被篩掉了。優化如下:

int maxx=1000000;
long long prime[maxx];
bool isPrime[maxx];
void Eratosthenes()
{
    memset(isPrime,1,sizeof(isPrime));
    isPrime[1]=0;
    int m=sqrt(maxx+0.5)
    for(int i=2;i<=m;++i)
    {
        if(isPrime[i])
        {
            for(int j=i*i;j<=maxx;j+=i)
                isPrime[j]=0;
        }
    }
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章