はじめに
この実験では、Java で数が素数であるかどうかをチェックする方法を学びます。まず、素数性を判断する基本的なループを実装します。
次に、数の平方根を利用して素数チェックのプロセスを最適化します。最後に、負の数や整数でない入力を適切に処理するようにコードを改良します。
この実験では、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
これで、異なるタイプの入力を試してみましょう。
プログラムがこれらの異なる入力をどのように処理し、有効な正の整数を入力するまで入力を促すかを観察してください。
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 つ前まで繰り返すループを使用して、割り切れるかどうかをチェックする基本的な素数チェックを実装しました。この最初のアプローチにより、素数の定義とそのアルゴリズムの実装についての基本的な理解が得られました。
次に、素数チェックの効率を向上させるための最適化を検討しました。これには、数の平方根までの約数のみをチェックすればよいことを理解することが含まれており、大きな入力に対して必要な繰り返し回数を大幅に削減します。最後に、負の数と整数でない入力を処理することでエッジケースに対応し、素数チェック機能をより堅牢で完全なものにしました。