判斷一個數是否爲素數(質數)

定義

質數是指在大於1的天然數中,除了1和它自己之外再也不有其餘因數的天然數。算法

實現

直觀的方法

int isprime(int x) {
    if (x < 2) return false; // 小於2的數都不是質數
    for (int i = 2; i < x; i++)
        if (x % i == 0) return false;
    return true;
}

顯然這個算法的複雜度爲\(O(n)\)數組

更快的方法

咱們知道,一個數若是能夠進行因數分解,那麼分解時獲得的兩個數必定是一個小於等於\(sqrt(n)\),一個大於等於\(sqrt(n)\)。因此,循環沒有必要從\(2\)\(x-1\),只須要從\(2\)\(sqrt(n)\)就行了,那麼這個算法的時間複雜度就爲\(O\left(sqrt(n)\right)\)優化

int isprime(int x) {
    if (x < 2) return false; // 小於2的數都不是質數
    for (int i = 2; i <= int(sqrt(x)); i++) // 從2到sqrt(x)
        if (x % i == 0) return false;
    return true;
}

固然,這個算法還能夠繼續優化,咱們能夠判斷2是否是這個數的約數,而後就能夠從\(3\)開始循環到\(sqrt(n)\)了,每次循環\(i+2\),那麼這個算法的複雜度就爲\(O(sqrt(n)/2)\)spa

int isprime(int x) {
    if (x < 2) return false; // 小於2的數都不是質數
    if (x != 2 && x % 2 == 0) return false; // 不是2且能被2整除的數都不是質數
    for (int i = 3; i <= int(sqrt(x)); i += 2) // 每次循環加2
        if (x % i == 0) return false;
    return true;
}

還有更快的嗎?——埃拉託斯特尼篩法

即便是上述的算法,在遇到很大的數字\((n\ge{100,000,000})\)的時候,仍是很慢。
那還有沒有更快的算法呢?答案是有的,埃拉託斯特尼篩法就是其中之一。.net

咱們能夠把從\(2\)\(maxn\)的數儲存爲一張表,例如bool prime[MAXN];
而後咱們一詞遍歷這個數組,把\(i\)的倍數從數組中去掉,這樣咱們就獲得了一張從\(2\)\(maxn\)的質數的表。
須要判斷一個數是否爲質數的時候只須要查詢這張表就能夠了,例如if (prime[i]) // 你的操做code

void getPrime(int maxn) {
    for (int i = 0; i <= maxn; i++) prime[i] = 1; // 所有定義爲質數 
    prime[0] = prime[1] = 0;
    for (int i = 2; i <= maxn; i++) {
        if (!prime[i]) continue;
        for (int j = i * 2; j <= maxn; j += i) prime[j] = 0; // i的倍數標記爲合數 
    }
}

引用

素數的四種判斷方法、實現及比較:http://www.javashuo.com/article/p-nnilbdev-eh.htmlblog

相關文章
相關標籤/搜索