2

以下は、Java で (インターネットの助けを借りて) 私が最初に作成したプログラムの 1 つです。指定された整数が素数かどうかをチェックし、ユーザーにフィードバックを求めるプログラムです。ユーザー入力が整数でない場合、整数ではないことを出力します。後者は、Big Integers が入力されたときにも発生します。これはコードです:

import java.util.Scanner;

class BasicPrime1 {
    public static void main(String[] args) {

        try {
            System.out.println("Enter an Integer: ");
            Scanner sc = new Scanner(System.in);

            int i; 
            int number = Integer.parseInt(sc.nextLine());

        // 1 and numbers smaller than 1 are not prime
            for (i = 1; number <= i;) {
                System.out.println("NOT a prime!");
                break;
            }

        // Number is not prime if the remainder of a division (modulus) is 0
            for (i = 2; i < number; i++) {  
                int n = number % i;         
                if (n == 0) {                 
                    System.out.println("NOT a prime!");
                    break;
                }  
            }

        // I do not understand why the if-statement below works.
            if(i == number) { 
                System.out.println("YES! PRIME!");
            }
        }

        catch(NumberFormatException nfe) {
            System.out.println("Not an integer!");
        }

    }
}

このプログラムは彼の仕事をしますが、なぜ if ステートメントの部分が機能するのかわかりません。「i == number」が真の値を与える可能性があるのはどうしてですか(素数を入力すると「YES! PRIME」と出力されます)。ローカル変数 i は for ループでインクリメントされますが、if ステートメントは for ループの外にあります。

/edit以下の段落はナンセンスであるとJim Lewis が指摘して
いるように、今考えてみると、これが事実であると私が考えることができる唯一の理由は、== 演算子が i-'object' と number-'object' が属するかどうかをチェックするためです。同じ「タイプ」に (つまり、同じオブジェクトへの参照を持っている)。どちらもプリミティブ整数の型に属しているため、このプログラムは整数をキャッチします (他の入力は NumberFormatException をスローし、キャッチされて「整数ではありません」を出力します)。素数であるものが最初の for ループを通過すると、魔法の if ステートメントが "true" を返し、"YES! PRIME!" を出力します。

私は正しい軌道に乗っていますか?

私は魔法の if ステートメントを削除し、次のような if-else ステートメントに変更することで、このプログラムを改善まし

boolean factorFound = false;            
for (i = 2; i < Math.sqrt(number) + 1; i++) {
    int n = number % i;
    if (n == 0) {
        factorFound = false;
        break;
    }  
    else {
        factorFound = true; 
    }
}
if(factorFound == false) System.out.println("NOT a prime!");
if(factorFound == true) System.out.println("YES! PRIME!");

入力数値の平方根まで上げるだけで、計算時間が改善されます (奇数をチェックするか、AKS Primality Testを使用するだけでさらに改善できることはわかっていますが、それは重要ではありません)。

私の主な質問は、最初のプログラム (魔法の if ステートメントを使用) の効率を同じ方法で改善できなかった理由です。最初のプログラムで "(i = 2; i < Math.sqrt(number) + 1; i++)" のように for ループを強化すると、"YES! PRIME!" が出力されなくなります。素数を入力したとき。空白を与えます。私の以前の説明が正しかったとしても、おそらくそうではありませんが、これは説明されていません。

あなたは私を啓発するかもしれません。

回答: int i は for ループの範囲外であり、 for ループを number まで複数回通過した後、 i の値は、素数であることが確認できる場合、値 number に到達します。さらに、消える「YES! PRIME!」を確認すると、if ステートメントと for ループの両方で number を ( Math.sqrt(number) + 1 ) に変更し、コードを動作させることが実際に可能であることがわかりました。したがって、質問は誤った前提に基づいていました。

4

2 に答える 2

1

// 以下の if ステートメントが機能する理由がわかりません

説明: i が number に等しくなるまでインクリメントされたためです。sqrt(number) で停止すると、if ステートメントは常に失敗します。

ところで、整数に平方根を使うのは好きではありません。私は isPrime 関数のほうが好きです:

        if (number < 2) return false;
        if (number > 2 && number % 2 == 0) return false;
        for (int i = 3; i * i <= number; i = i + 2)
            if (number % i == 0) return false;
        return true;
于 2013-08-22T22:30:34.863 に答える