はじめに
この実験では、Java で数が素数であるかどうかをチェックする方法を学びます。まず、素数性を判断する基本的なループを実装します。
次に、数の平方根を利用して素数チェックのプロセスを最適化します。最後に、負の数や整数でない入力を適切に処理するようにコードを改良します。
基本的な素数チェックループを実装する
このステップでは、基本的なループを使用して、与えられた数が素数であるかどうかをチェックする Java プログラムを作成します。素数とは、1 より大きい自然数で、1 とそれ自身以外に正の約数を持たない数です。
まだ開いていない場合は、WebIDE エディタで
HelloJava.javaファイルを開きます。ファイルの内容全体を次のコードに置き換えます。
import java.util.Scanner; public class HelloJava { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter a positive integer: "); int number = scanner.nextInt(); if (number <= 1) { System.out.println(number + " is not a prime number."); } else { boolean isPrime = true; for (int i = 2; i < number; i++) { if (number % i == 0) { isPrime = false; break; // Exit the loop early if a divisor is found } } if (isPrime) { System.out.println(number + " is a prime number."); } else { System.out.println(number + " is not a prime number."); } } scanner.close(); } }このコードの新しい部分を理解しましょう。
- 引き続き
Scannerを使用してユーザーからの入力を取得します。 int number = scanner.nextInt();:この行は、ユーザーが入力した整数値を読み取り、number変数に格納します。if (number <= 1):数が 1 以下であるかどうかをチェックします。1 以下の数は素数とは見なされません。boolean isPrime = true;:isPrimeというboolean型の変数を導入し、trueに初期化します。これを使用して、数が素数であるかどうかを追跡します。for (int i = 2; i < number; i++):これはforループです。iを 2 から始め、iがnumberより小さい限り続きます。各反復でiは 1 ずつ増加します。1 は常に約数であり、1 と数自身以外の約数を探しているため、2 から約数をチェックし始めます。if (number % i == 0):ループ内で、この行はnumberがiで割り切れるかどうか(除算の余りが 0 かどうか)をチェックします。割り切れる場合、1 と数自身以外の約数を見つけたことになります。isPrime = false;:約数が見つかった場合、isPrimeをfalseに設定します。break;:この文はforループを即座に終了します。1 つの約数を見つけたら、その数は素数ではないことがわかるので、さらにチェックする必要はありません。- 最後に、
isPrimeの値をチェックして、数が素数であるかどうかを出力します。
- 引き続き
ファイルを保存します(Ctrl+S または Cmd+S)。
ターミナルで修正したプログラムをコンパイルします。
javac HelloJava.javaコンパイルエラーがなければ、
HelloJava.classファイルが作成されます。コンパイルしたプログラムを実行します。
java HelloJavaプログラムは、正の整数の入力を求めます。数(例:7)を入力し、Enter キーを押します。プログラムは、その数が素数であるかどうかを表示します。4、11、1、または 0 などの異なる数を入力して、出力を確認してみてください。
Enter a positive integer: 7 7 is a prime number.Enter a positive integer: 4 4 is not a prime number.
Java でループを使用した基本的な素数チェッカーを正常に実装しました!
平方根を使って素数チェックを最適化する
前のステップでは、素数チェックのループは 2 から数自身まで繰り返されました。これは機能しますが、非常に大きな数に対しては非効率的です。数の平方根までの約数のみをチェックすることで、これを最適化することができます。
この最適化が機能する理由は次の通りです。数 n がその平方根より大きい約数 d(d > sqrt(n))を持つ場合、d * d' = n となる別の約数 d' が必ず存在します。この別の約数 d' は平方根より小さい(d' < sqrt(n))必要があります。したがって、数が 1 とそれ自身以外の約数を持つ場合、その平方根以下の約数を少なくとも 1 つ持っているはずです。そのため、平方根までの約数をチェックするだけで済みます。
WebIDE エディタで
HelloJava.javaファイルを開きます。mainメソッド内のforループを修正して、数の平方根までのみ繰り返すようにします。既存のforループブロックを次のコードに置き換えます。// ... (previous code) ... if (number <= 1) { System.out.println(number + " is not a prime number."); } else { boolean isPrime = true; // Optimize the loop to check up to the square root int limit = (int) Math.sqrt(number); for (int i = 2; i <= limit; i++) { if (number % i == 0) { isPrime = false; break; // Exit the loop early if a divisor is found } } if (isPrime) { System.out.println(number + " is a prime number."); } else { System.out.println(number + " is not a prime number."); } } // ... (rest of the code) ...変更点を見てみましょう。
int limit = (int) Math.sqrt(number);:Math.sqrt()を使用してnumberの平方根を計算します。このメソッドはdoubleを返すため、ループカウンタiが整数であるため、intにキャストします。この値をlimitという変数に格納します。for (int i = 2; i <= limit; i++):ループは現在、2 から計算されたlimit(平方根の整数部分)まで繰り返されます。
ファイルを保存します(Ctrl+S または Cmd+S)。
ターミナルで最適化されたプログラムをコンパイルします。
javac HelloJava.java再び、エラーがなければ
HelloJava.classファイルが生成されます。コンパイルされたプログラムを実行します。
java HelloJava異なる数を入力して、最適化された素数チェッカーをテストします。以前と同じ結果が得られるはずですが、非常に大きな数に対しては、このバージョンの方が速くなります。
Enter a positive integer: 29 29 is a prime number.Enter a positive integer: 100 100 is not a prime number.
ループの繰り返し回数を減らすことで、素数チェックプログラムを正常に最適化しました。
負の数と整数以外の入力を処理する
前のステップでは、プログラムはユーザーが常に正の整数を入力することを前提としていました。しかし、実際のアプリケーションでは、ユーザーが負の数、ゼロ、または整数でないテキストを入力する可能性があります。現在のプログラムでは、これらのケースを適切に処理できません。このステップでは、負の数と整数でない入力を処理するためのチェックを追加します。
WebIDE エディタで
HelloJava.javaファイルを開きます。mainメソッドを修正して、負の数のチェックを含め、ユーザーが有効な正の整数を入力するまでループするようにします。mainメソッド内の既存のコードを次のコードに置き換えます。import java.util.Scanner; import java.util.InputMismatchException; // Import this class public class HelloJava { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int number = 0; boolean validInput = false; // Loop until valid positive integer input is received while (!validInput) { System.out.print("Enter a positive integer: "); try { number = scanner.nextInt(); if (number > 0) { validInput = true; // Input is valid, exit loop } else { System.out.println("Please enter a positive integer (greater than 0)."); } } catch (InputMismatchException e) { System.out.println("Invalid input. Please enter an integer."); scanner.next(); // Consume the invalid input to prevent infinite loop } } // Now, perform the prime check on the valid positive number if (number <= 1) { // This check is technically redundant now due to the input loop, but good for clarity System.out.println(number + " is not a prime number."); } else { boolean isPrime = true; int limit = (int) Math.sqrt(number); for (int i = 2; i <= limit; i++) { if (number % i == 0) { isPrime = false; break; } } if (isPrime) { System.out.println(number + " is a prime number."); } else { System.out.println(number + " is not a prime number."); } } scanner.close(); } }新しく追加された部分を分解してみましょう。
import java.util.InputMismatchException;:ユーザーが整数でないものを入力した場合を処理するために、このクラスをインポートします。int number = 0; boolean validInput = false;:numberとboolean型のフラグvalidInputを初期化します。while (!validInput):これはwhileループで、validInputがfalseである限り実行されます。try { ... } catch (InputMismatchException e) { ... }:これはtry-catchブロックです。tryブロック内のコードが実行されます。InputMismatchExceptionが発生した場合(つまり、入力が整数でなかった場合)、catchブロック内のコードが実行されます。number = scanner.nextInt();:整数を読み取ろうとします。if (number > 0):tryブロック内で、入力された数が正であるかどうかをチェックします。正であれば、validInputをtrueに設定してループを終了します。System.out.println("Please enter a positive integer (greater than 0).");:数が正でない場合、エラーメッセージを出力します。System.out.println("Invalid input. Please enter an integer.");:catchブロック内で、InputMismatchExceptionが発生した場合、エラーメッセージを出力します。scanner.next();:これはcatchブロック内で重要です。スキャナーから無効な入力を消費し、プログラムが同じ無効な入力を読み続ける無限ループを防ぎます。
ファイルを保存します(Ctrl+S または Cmd+S)。
更新されたプログラムをコンパイルします。
javac HelloJava.javaプログラムを実行します。
java HelloJavaこれで、異なるタイプの入力を試してみましょう。
- 正の整数を入力します(例:13)。
- 負の整数を入力します(例:-5)。
- ゼロを入力します(0)。
- テキストを入力します(例:"hello")。
プログラムがこれらの異なる入力をどのように処理し、有効な正の整数を入力するまで入力を促すかを観察してください。
Enter a positive integer: -5 Please enter a positive integer (greater than 0). Enter a positive integer: 0 Please enter a positive integer (greater than 0). Enter a positive integer: hello Invalid input. Please enter an integer. Enter a positive integer: 17 17 is a prime number.
ループと例外処理を使用して負の数と整数でない入力を処理することで、素数チェックプログラムをより堅牢にすることに成功しました。
まとめ
この実験では、Java で数が素数かどうかをチェックする方法を学びました。まず、2 から数の 1 つ前まで繰り返すループを使用して、割り切れるかどうかをチェックする基本的な素数チェックを実装しました。この最初のアプローチにより、素数の定義とそのアルゴリズムの実装についての基本的な理解が得られました。
次に、素数チェックの効率を向上させるための最適化を検討しました。これには、数の平方根までの約数のみをチェックすればよいことを理解することが含まれており、大きな入力に対して必要な繰り返し回数を大幅に削減します。最後に、負の数と整数でない入力を処理することでエッジケースに対応し、素数チェック機能をより堅牢で完全なものにしました。



