以下は、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 ) に変更し、コードを動作させることが実際に可能であることがわかりました。したがって、質問は誤った前提に基づいていました。