Java で数が素数かどうかをチェックする方法

JavaJavaBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Java で数が素数であるかどうかをチェックする方法を学びます。まず、素数性を判断する基本的なループを実装します。

次に、数の平方根を利用して素数チェックのプロセスを最適化します。最後に、負の数や整数でない入力を適切に処理するようにコードを改良します。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java/BasicSyntaxGroup -.-> java/operators("Operators") java/BasicSyntaxGroup -.-> java/booleans("Booleans") java/BasicSyntaxGroup -.-> java/if_else("If...Else") java/BasicSyntaxGroup -.-> java/for_loop("For Loop") java/BasicSyntaxGroup -.-> java/while_loop("While Loop") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/user_input("User Input") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/exceptions("Exceptions") java/SystemandDataProcessingGroup -.-> java/math_methods("Math Methods") subgraph Lab Skills java/operators -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} java/booleans -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} java/if_else -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} java/for_loop -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} java/while_loop -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} java/user_input -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} java/exceptions -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} java/math_methods -.-> lab-559969{{"Java で数が素数かどうかをチェックする方法"}} end

基本的な素数チェックループの実装

このステップでは、基本的なループを使用して、与えられた数が素数であるかどうかをチェックする Java プログラムを作成します。素数とは、1 より大きい自然数で、1 とそれ自身以外に正の約数を持たない数です。

  1. まだ開いていない場合は、WebIDE エディタで HelloJava.java ファイルを開きます。

  2. ファイルの内容全体を次のコードに置き換えます。

    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 から始め、inumber より小さい限り続きます。各反復で i は 1 ずつ増加します。1 は常に約数であり、1 と数自身以外の約数を探しているため、2 から約数をチェックし始めます。
    • if (number % i == 0):ループ内で、この行は numberi で割り切れるかどうか(除算の余りが 0 かどうか)をチェックします。割り切れる場合、1 と数自身以外の約数を見つけたことになります。
    • isPrime = false;:約数が見つかった場合、isPrimefalse に設定します。
    • break;:この文は for ループを即座に終了します。1 つの約数を見つけたら、その数は素数ではないことがわかるので、さらにチェックする必要はありません。
    • 最後に、isPrime の値をチェックして、数が素数であるかどうかを出力します。
  3. ファイルを保存します(Ctrl+S または Cmd+S)。

  4. ターミナルで修正したプログラムをコンパイルします。

    javac HelloJava.java

    コンパイルエラーがなければ、HelloJava.class ファイルが作成されます。

  5. コンパイルしたプログラムを実行します。

    java HelloJava
  6. プログラムは、正の整数の入力を求めます。数(例: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 がその平方根より大きい約数 dd > sqrt(n))を持つ場合、d * d' = n となる別の約数 d' が必ず存在します。この別の約数 d' は平方根より小さい(d' < sqrt(n))必要があります。したがって、数が 1 とそれ自身以外の約数を持つ場合、その平方根以下の約数を少なくとも 1 つ持っているはずです。そのため、平方根までの約数をチェックするだけで済みます。

  1. WebIDE エディタで HelloJava.java ファイルを開きます。

  2. 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(平方根の整数部分)まで繰り返されます。
  3. ファイルを保存します(Ctrl+S または Cmd+S)。

  4. ターミナルで最適化されたプログラムをコンパイルします。

    javac HelloJava.java

    再び、エラーがなければ HelloJava.class ファイルが生成されます。

  5. コンパイルされたプログラムを実行します。

    java HelloJava
  6. 異なる数を入力して、最適化された素数チェッカーをテストします。以前と同じ結果が得られるはずですが、非常に大きな数に対しては、このバージョンの方が速くなります。

    Enter a positive integer: 29
    29 is a prime number.
    Enter a positive integer: 100
    100 is not a prime number.

ループの繰り返し回数を減らすことで、素数チェックプログラムを正常に最適化しました。

負の数と整数でない入力の処理

前のステップでは、プログラムはユーザーが常に正の整数を入力することを前提としていました。しかし、実際のアプリケーションでは、ユーザーが負の数、ゼロ、または整数でないテキストを入力する可能性があります。現在のプログラムでは、これらのケースを適切に処理できません。このステップでは、負の数と整数でない入力を処理するためのチェックを追加します。

  1. WebIDE エディタで HelloJava.java ファイルを開きます。

  2. 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;numberboolean 型のフラグ validInput を初期化します。
    • while (!validInput):これは while ループで、validInputfalse である限り実行されます。
    • try { ... } catch (InputMismatchException e) { ... }:これは try-catch ブロックです。try ブロック内のコードが実行されます。InputMismatchException が発生した場合(つまり、入力が整数でなかった場合)、catch ブロック内のコードが実行されます。
    • number = scanner.nextInt();:整数を読み取ろうとします。
    • if (number > 0)try ブロック内で、入力された数が正であるかどうかをチェックします。正であれば、validInputtrue に設定してループを終了します。
    • 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 ブロック内で重要です。スキャナーから無効な入力を消費し、プログラムが同じ無効な入力を読み続ける無限ループを防ぎます。
  3. ファイルを保存します(Ctrl+S または Cmd+S)。

  4. 更新されたプログラムをコンパイルします。

    javac HelloJava.java
  5. プログラムを実行します。

    java HelloJava
  6. これで、異なるタイプの入力を試してみましょう。

    • 正の整数を入力します(例: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 つ前まで繰り返すループを使用して、割り切れるかどうかをチェックする基本的な素数チェックを実装しました。この最初のアプローチにより、素数の定義とそのアルゴリズムの実装についての基本的な理解が得られました。

次に、素数チェックの効率を向上させるための最適化を検討しました。これには、数の平方根までの約数のみをチェックすればよいことを理解することが含まれており、大きな入力に対して必要な繰り返し回数を大幅に削減します。最後に、負の数と整数でない入力を処理することでエッジケースに対応し、素数チェック機能をより堅牢で完全なものにしました。