1. 程式人生 > >判斷素數方法(二)

判斷素數方法(二)

效率 out 用處 感覺 sin i++ 大於 urn 優化

判斷素數的方法(二)

前面那篇文章寫了素數的判斷方法,現在講下如何在區間中篩選出全部素數。

方法一

既然已經可以判斷素數了,自然可以通過判斷素數的方法來依次判斷素數,從而進行篩選,請原諒我的表述能力,代碼如下

#include<bits/stdc++.h>
using namespace std;
inline int prime(int x)
{
    for (int i = 2; i <= sqrt(x); i++)
        if (x%i == 0)
            return 0;
    return 1;
}

int main()
{
    int left, right;
    cin >> left >> right;
    for (int i = left; i <= right; i++)
        if (prime(i) == 1)
            cout << i << " ";
}

但這個時間復雜度好像有點高,假設從[100,500]這個區間,要執行1878次,執行判斷的復雜度是O(sqrt(n)),外循環是O(n),所以總復雜度是O(n*sqrt(n)),其實效率並不高,讓我們想辦法優化下...

方法二

這個方法我高中自己莫名其妙來的靈感,哦豁,有點小驕傲,思考下素數的定義:質數定義為在大於1的自然數中,除了1和它本身以外不再有其他因數 ,反正百度是這麽寫的qaq,那麽換句話說,只要是除1意外任何數字的倍數就一定不是素數了,比如2,2的倍數是4,6,8,10,等等,那就一定不是素數了,3的倍數6,9,12,一定不是素數了。
這有什麽用處呢。感覺一切描述都是蒼白的,好吧,其實是我不會描述

,直接上代碼吧

#include<bits/stdc++.h>
using namespace std;
const int MAXV = 10001;
int XX[MAXV];
void init(int left, int right)
{
    for (int i = 2; i <= right; i++)
    {
        int k = 2;
        while (i*k <= right)
        {
            XX[i*k] = 1;
            k++;
        }
    }
    for (int i = left; i <= right; i++)
        if (!XX[i])
            cout << i << " ";
}
int main()
{
    int myleft, myright;
    cin >> myleft >> myright;
    init(myleft,myright);
}

我們接著假設[100,500]這個區間,看看他到底執行多少次,2192次。
什麽2192次,那不是比上面那個還高麽,讓我們把數據區間放大一點..[100,9999]試下,73647次,而上面那個算法需要117291次,隨著數據增大,優勢越來越明顯,其實我們還可以優化上面那個篩選算法。
試想一下4這個數字,他已經被2篩選了,這就意味這4的倍數也一定是2的倍數,那麽後面4的倍數這個循環就不用做了,讓我們試試,先付下代碼

#include<bits/stdc++.h>
using namespace std;
const int MAXV = 10001;
int XX[MAXV];
int mycount= 1;
void init(int left, int right)
{
    for (int i = 2; i <= right; i++)
    {
        if(XX[i]==1)
            continue;
        int k = 2;
        while (i*k <= right)
        {
            XX[i*k] = 1;
            k++;
        }
    }
    for (int i = left; i <= right; i++)
        if (!XX[i])
            cout << i << " ";
}

int main()
{
    int myleft, myright;
    cin >> myleft >> myright;
    init(myleft,myright);
    cout << endl;
    cout << mycount;

}

代碼很簡單,在篩素數的前面加個判斷就行。讓我們測試下運行次數,哇23070次,這真的是一個偉大的改進。速度翻了一番還多。
其實這個算法很早就有了,反正叫啥我布吉島
先就這樣吧~~~~~

判斷素數方法(二)