1. 程式人生 > >Java實現整型素數判斷

Java實現整型素數判斷

前言

定義判別法

定義優化判別法

孿生素數性質判別法

 Matlab版素數判別法

後記


前言

        素數判斷的依據是它的定義和它的性質。參考百度百科,素數被定義是一個大於1且只有1和它本身兩個因數的自然數。而它的性質就非常多了,深入起來也非常之麻煩,在後面的演算法實現中,我也只使用了孿生素數中的一個性質來判斷素數。

定義判別法

        根據素數的定義我們可以利用餘數性質來進行判斷,如果一個數不能整除小於它的任意一個數,那麼它就是素數。其實我們無需從1到n-1開始整除,只需在2到√n,具體的原因參見:

為什麼判斷素數需要遍歷到它的平方根?程式碼如下:

public static boolean isPrime(int n){
    if(n < 0){
        throw new IllegalArgumentException("N must be a non negative integer.");
    }
    if(n < 4){
        return n > 1;
    }
    for(int i = 2, limit = (int) Math.sqrt(n); i <= limit; i++){
        if(n % i == 0){
            return false;
        }
    }
    return true;
}

定義優化判別法

        其實我們這裡也可以稍微優化,因為除了2以外的偶數,全部都是合數,因此我們可以先判斷n是否為偶數,然後n一定是奇數,接著我們就可以按照3:2:√n來逐個判斷,需要判斷的數量減少。程式碼如下:

public static boolean isPrime(int n){
    if(n < 0){
        throw new IllegalArgumentException("N must be a non negative integer.");
    }
    if(n < 4){
        return n > 1;
    }
    if((n & 1) == 0){
        return false;
    }
    for(int i = 3, limit = (int) Math.sqrt(n); i <= limit; i += 2){
        if(n % i == 0){
            return false;
        }
    }
    return true;
}

孿生素數性質判別法

        關於孿生素數的判別證明,可以參考這篇部落格:素數(質數)判斷方法。程式碼如下:

public static boolean isPrime(int n){
    if(n < 0){
        throw new IllegalArgumentException("N must be a non negative integer.");
    }
    if(n < 4){
        return n > 1;
    }
    int remainder = n % 6;
    if(remainder != 1 && remainder != 5){
        return false;
    }
    for(int i = 5, limit = (int) Math.sqrt(n); i <= limit; i += 6){
        if(n % i == 0 || n % (i + 2) == 0){
            return false;
        }
    }
    return true;
}

 Matlab版素數判別法

        Matlab2014a版內建的isprime方法,它是先提取出小於等於√n的所有素數值,然後用n逐個對這些素數求餘,如果有一個求餘不等於0,則說明n為合數,否則n為素數,它的依據主要來自√n的性質。程式碼如下:

public static boolean isPrime(int n){
    if(n < 0){
        throw new IllegalArgumentException("N must be a non negative integer.");
    }
    if(n < 4){
        return n > 1;
    }
    for(int prime : primes((int) Math.sqrt(n))){
        if(n % prime == 0){
            return false;
        }
    }
    return true;
}

        程式碼中的primes方法參見:Java實現快速查詢某個範圍內的所有素數。該方法在Java平臺可能執行效率不是很高,但是Matlab對矩陣化操作進行了極致優化,因此在Matlab平臺該方法執行效率非常快。可見一個平臺上效率高的演算法,並不代表在其他語言平臺上效率更高,因此在平臺上寫演算法時,還是要注意相關平臺的側重點。

後記

        這篇文章我是對整型範圍的資料進行素數判斷,資料的最大值為2147483647,如果對於超大資料,就應該選擇其他方法,比如Miller_Rabbin素數判別法,具體問題具體分析。