1. 程式人生 > >java素數篩選法

java素數篩選法

判斷是否為素數
對於一個任意一個正整數,如果它只能被自身或1整除,稱其為素數,否則為合數。1比較特殊,既不是質數也不是合數。

基於素數的定義,很快就可以直觀的想到程式碼,對於任意一個正整數,只需要在(1,n)也就是[2,n-1]之間進行遍歷,如果n可以被區間中的任何一個數字整除,它就不是質數。否則,如果對整個區間遍歷完畢,還未找到一個數字可以整除n,那麼這個數字就是質數。

public Test{
    //類方法
    public static bool isPrime(int n){
        for(int i=2;i<=n-1;++i){
            if
(n%i==0){ return false; } } return true; } }

演算法時間複雜度分析:對於上邊窮舉遍歷暴力的方法,判斷一個正整數是否為素數。所需的時間複雜度是O(n),然而在實際應用中,判斷某一個數字是否為為素數只是整個程式當中的一小部分,這樣的時間複雜度相對而言還是比較高的。
下面將一種時間複雜度為O(n^(1/2))時間複雜的判斷素數的演算法。

數學背景:對於任意一個正整數N,可以將其分解為兩個因數。特殊情況下N^(1/2)相等,即N=N^(1/2)*N^(1/2)。此外若存在兩個因數,則其中一個必然大於N^(1/2),而另外一個必然小於N^(1/2)。因此,只需要在區間[2,N^(1/2)]區間遍歷即可,若在此區間存在一個正整數使得N被整除,則其為合數(此時這個因數小於N^(1/2),而另外一個因數必然大於N^(1/2))

,否則其為質數。進過這樣的 處理可以顯著的降低判斷是否為質數演算法的時間複雜度,達到O(n^(1/2))。

public Test{
        public static bool isPrime(int n){
        for(int i=2;i<=Math.sqrt(n*1.0);++i){
            if(n%i == 0){
                return false;
            }
        }
        return true;
    }
}

素數篩選法:從小到大遍歷每一個數字,將其倍數篩去,剩下的即為素數。

class Test{
    private boolean[] p;//用於標記對應下標的數字是否為素數
    private int[] prime;
    private int len=0;

    //構造方法
    Test(int n){
        p = new boolean[n];
        prime = new int[n];
    }

    public void prime(int n){
        for(int i=2;i<n;++i){
            if(p[i]==false){
                prime[len++] = i;//false表示對應下標為素數
                //進行篩選
                for(int j=i+i;j<n;j+=i){
                    p[j] = true;//標記不是素數
                }
            }
        }
    } 

    public void show(int n){
        for(int i=0;i<n;++i){
            System.out.print(prime[i]+" ");
        }
    }
}

public class Main{
    public static void main(String[] args){
        Test t = new Test(100);
        t.prime(100);
        t.show(100);
    }
}

輸出100範圍內的素數:
這裡寫圖片描述