1. 程式人生 > >九度oj--1047素數判定

九度oj--1047素數判定

題目描述:
給定一個數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 + " ");
            }
       }
    }
}