判斷一個數是不是質數(素數),3種方式介紹

Candy_GL發表於2019-03-27

一、概念介紹
    大家中學都學過,就不過多介紹了,大致提兩點:

    質數又稱素數。一個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做質數;否則稱為合數。
    0和1既不是質數也不是合數,最小的質數是2
 

二、方法介紹
1.最直觀,但效率最低的寫法
public static boolean isPrime(int n){
    if (n <= 3) {
        return n > 1;
    }
    for(int i = 2; i < n; i++){
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}
    這裡特殊處理了一下小於等於3的數,因為小於等於3的自然數只有2和3是質數。

    然後,我們只需要從2開始,一直到小於其自身,依次判斷能否被n整除即可,能夠整除則不是質數,否則是質數。

 

2.初步優化
    假如n是合數,必然存在非1的兩個約數p1和p2,其中p1<=sqrt(n),p2>=sqrt(n)。由此我們可以改進上述方法優化迴圈次數。如下:

public static boolean isPrime(int n) {
    if (n <= 3) {
        return n > 1;
    }
    int sqrt = (int)Math.sqrt(n);
    for (int i = 2; i <= sqrt; i++) {
        if(n % i == 0) {
            return false;
        }
    }
    return true;
}
 

3.繼續優化
    我們繼續分析,其實質數還有一個特點,就是它總是等於 6x-1 或者 6x+1,其中 x 是大於等於1的自然數。

    如何論證這個結論呢,其實不難。首先 6x 肯定不是質數,因為它能被 6 整除;其次 6x+2 肯定也不是質數,因為它還能被2整除;依次類推,6x+3 肯定能被 3 整除;6x+4 肯定能被 2 整除。那麼,就只有 6x+1 和 6x+5 (即等同於6x-1) 可能是質數了。所以迴圈的步長可以設為 6,然後每次只判斷 6 兩側的數即可。

public static boolean isPrime(int num) {
    if (num <= 3) {
        return num > 1;
    }
    // 不在6的倍數兩側的一定不是質數
    if (num % 6 != 1 && num % 6 != 5) {
        return false;
    }
    int sqrt = (int) Math.sqrt(num);
    for (int i = 5; i <= sqrt; i += 6) {
        if (num % i == 0 || num % (i + 2) == 0) {
            return false;
        }
    }
    return true;
}
    對於輸入的自然數 n 較小時,也許效果不怎麼明顯,但是當 n 越來越大後,該方法的執行效率就會越來越明顯了。
--------------------- 
作者:阿飛__ 
來源:CSDN 
原文:https://blog.csdn.net/afei__/article/details/80638460 
版權宣告:本文為博主原創文章,轉載請附上博文連結!

相關文章