Eratosthenes篩選法(埃拉託斯特尼篩法)

                                                      Eratosthenes篩選法

主要用於求素數,時間複雜度爲O(nloglogn),比歐拉篩選法要慢,故我一般不用改法。


由於一個合數總是可以分解成若干個質數的乘積,那麼如果把質數的倍數都去掉,那麼剩下的就是質數了.Eratosthenes篩選法的思想特別簡單:對於不超過n的每個非負整數p,刪除2p,3p,4p,...,當處理完所有數之後,還沒有被刪除的就是素數.如果用vis[i]表示i已經被刪除,則篩選法的代碼可以寫成:

void isprime(int n)///篩選1-n的素數
{
    memset(vis,0,sizeof(vis));
    for(int i = 2; i <= n; i++)
        for(int j = 2 * i; j <= n; j += i)
            vis[j] = 1;
}

儘管代碼已經相當高效了,但仍然可以進行改進.首先,在"對於不超過n的每個非負數p"中,p可以限定爲素數--只需在第二重循環前加一個判斷if(!vis[i])即可.另外,內層循環也不必從* 2開始--它已經在= 2時被篩選了.改進後代碼如下:

void isprime(int n)///篩選1-n的素數
{
    memset(vis,0,sizeof(vis));
    int m = sqrt(n + 0.5);
    for(int i = 2; i <= m; i++)
    {
        if(!vis[i])
        {
            for(int j = i * i; j <= n; j += i)
                vis[j] = 1;
        }
    }
}

Eratosthenes篩選法雖然效率高,但是Eratosthenes篩選法做了許多無用功,一個數會被篩到好幾次,最後的時間複雜度是O(nloglogn),對於普通素數算法而言已經非常高效了,但歐拉篩選法的時間複雜度僅僅爲O(n).

歐拉算法見我另一篇素數高效打表法(歐拉篩選法)

轉載自https://blog.csdn.net/u012313335/article/details/47663801

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