java素數篩選法
阿新 • • 發佈:2019-01-23
判斷是否為素數
對於一個任意一個正整數,如果它只能被自身或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範圍內的素數: