九度oj--1047素數判定
阿新 • • 發佈:2019-01-22
題目描述:
給定一個數n,要求判斷其是否為素數(0,1,負數都是非素數)。
輸入:
測試資料有多組,每組輸入一個數n。
輸出:
對於每組輸入,若是素數則輸出yes,否則輸入no。
樣例輸入:
13
樣例輸出:
yes
方法一:試除法,把每一個比它小的數都除一遍
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
int a;
boolean isPrime;
while (cin.hasNext()){
a = cin.nextInt();
isPrime = true;
if(a < 2)//這裡容易錯,2是素數
isPrime = false;
else{
for(int i = 2 ; i < a ; i++){
if((a % i) == 0){
isPrime = false;
break ;
}
}
}
if(isPrime == true)
System.out.println("yes");
else
System.out.println("no");
}
}
}
改進:減少幾個迴圈,只需除到√m即可
(原因:因為如果m能被2~m-1之間任一整數整除,其二個因子必定有一個小於或等於√m,另一個大於或等於√m)
for(int i = 2 ; i <= Math.sqrt(a) ; i++){
方法二:費馬小定理+素數表
費馬小定理:對於兩個互質的素數N和P,必有:N^(P-1)%P=1
問題來了,當N和P很大時,乘方運算結果很大,而int最大隻有32位,怎麼辦?
這時,可以把Y個X相乘再取模的過程分解開來,比如:(17^25)%29則可分解為:( ( 17 * 17 ) % 29 * ( 17 * 17 ) % 29 * ……
這就是著名的“蒙格馬利”快速冪模演算法!
還要用到積模分解公式:
設有X、Y和Z三個正整數,則必有:(X*Y)%Z=((X%Z)*(Y%Z))%Z
對於給定的N,從素數表中取出任意的素數對其進行費馬測試,如果取了很多個素數,N仍未測試失敗,那麼則認為N是素數。當然,測試次數越多越準確,但一般來講50次就足夠了。
題目拓展:
輸入自然數n,要得到自然數n以內的全部素數
篩選法。即埃拉託斯特尼篩法:要得到自然數n以內的全部素數,必須把不大於√n的所有素數的倍數剔除,剩下的就是素數。
演算法如下:
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int m = (int)Math.ceil(Math.sqrt(n));
//初始化陣列值為0 0表示是素數,1表示不是素數
int[] arr = new int[n];
for(int i= 2 ; i < m ; i++){
if(arr[i] == 0){
for(int j = 2*i ; j < n ; j = j+i){
arr[j] = 1;
}
}
}
//輸出結果
for(int k = 2 ; k < n ; k++){
if(arr[k] == 0){
System.out.print(k + " ");
}
}
}
}