1. 程式人生 > >java中判斷素數的六種方法

java中判斷素數的六種方法

轉載地址:http://java.e800.com.cn/articles/2010/1110/1289376854382_1.html

 1. 根據概念判斷:

如果一個正整數只有兩個因子, 1和p,則稱p為素數.

public boolean isPrime(int n)

{

if(n < 2) return false;

for(int i = 2; i < n; ++i)

if(n%i == 0) return false;

return true;

}

時間複雜度O(n).

2. 改進, 去掉偶數的判斷

public boolean isPrime(int n)

{

if(n < 2) return false;

if(n == 2) return true;

if(n%2==0) return false;

for(int i = 3; i < n; i += 2)

if(n%i == 0) return false;

return true;

}

時間複雜度O(n/2), 速度提高一倍.

3. 進一步減少判斷的範圍

定理: 如果n不是素數, 則n有滿足1< d<=sqrt(n)的一個因子d.

證明: 如果n不是素數, 則由定義n有一個因子d滿足1< d< n.

如果d大於sqrt(n), 則n/d是滿足1< n/d<=sqrt(n)的一個因子.

public boolean isPrime(int n)

{

if(n < 2) return false;

if(n == 2) return true;

if(n%2==0) return false;

for(int i = 3; i*i <= n; i += 2)

if(n%i == 0) return false;

return true;

}

時間複雜度O(Math.sqrt(n)/2), 速度提高O((n-Math.sqrt(n))/2).

4. 剔除因子中的重複判斷.

定理: 如果n不是素數, 則n有滿足1< d<=Math.sqrt(n)的一個"素數"因子d.

證明: I1. 如果n不是素數, 則n有滿足1< d<=Math.sqrt(n)的一個因子d.

I2. 如果d是素數, 則定理得證, 演算法終止.

I3. 令n=d, 並轉到步驟I1.

由於不可能無限分解n的因子, 因此上述證明的演算法最終會停止.

// primes是遞增的素數序列: 2, 3, 5, 7, ...

// 更準確地說primes序列包含1->Math.sqrt(n)範圍內的所有素數

public boolean isPrime(int primes[], int n)

{

if(n < 2) return false;

for(int i = 0; primes[i]*primes[i] <= n; ++i)

if(n%primes[i] == 0) return false;

return true;

}

  5. 構造素數序列primes: 2, 3, 5, 7, ...

由4的演算法我們知道, 在素數序列已經被構造的情況下, 判斷n是否為素數效率很高;

下面程式可以輸出素數表.

public class ShowPrimeNumber{

public static int[] getPrimeNums(int maxNum){

int[] primeNums = new int[maxNum/2+1];

int sqrtRoot;

int cursor = 0;

boolean isPrime;

for(int i=2;i<=maxNum;i++){

sqrtRoot = (int)Math.sqrt(i); //取平方根

isPrime = true;

for(int j=0;j< cursor;j++){

if(primeNums[j]>sqrtRoot)

break;

if(i%primeNums[j]==0){

isPrime = false;

break;

}

}

if(isPrime){

primeNums[cursor++] = i;

}

}

int[] result = new int[cursor];

System.arraycopy(primeNums,0,result,0,cursor);

return result;

}

public static void main(String[] args) throws Exception{

int maxNum = Integer.parseInt(args[0]);

int[] primeNums = getPrimeNums(maxNum);

System.out.println("共"+primeNums.length+"個素數");

for(int i=0;i< primeNums.length;i++){

System.out.print(primeNums[i]+",\t");

}

}

}

6.(在素數表中)二分查詢

Arrays.BinarySearch方法:

該方法用於在指定陣列中查詢給定的值,採用二分法實現,所以要求傳入的陣列已經是排序了的。

該方法的基本語法格式為:

Static int binarySearch(byte[] a, byte key)

該方法返回資料中key元素所在的位置,如果沒有key元素,則返回key應插入的位置:-(insertion point-1),如陣列中的第一個元素就大於key,返回-1。

注:陣列的資料型別可以是int[] byte[] short[] float[] long[] double[] char[] Object[]型別。