如何在 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. 如果 HelloJava.java 文件尚未在 WebIDE 编辑器中打开,请打开它。

  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;:我们引入一个名为 isPrimeboolean 变量,并将其初始化为 true。我们将使用它来跟踪该数是否为质数。
    • for (int i = 2; i < number; i++):这是一个 for 循环。它从 i 等于 2 开始,只要 i 小于 number 就会继续执行。在每次迭代中,i 增加 1。我们从 2 开始检查除数,因为 1 总是一个除数,而我们要找的是除 1 和该数本身之外的除数。
    • if (number % i == 0):在循环内部,这行代码检查 number 是否能被 i 整除(即除法的余数为 0)。如果可以,这意味着我们找到了除 1 和该数本身之外的除数。
    • isPrime = false;:如果找到了除数,我们将 isPrime 设置为 false
    • break;:这个语句会立即退出 for 循环。一旦我们找到一个除数,就知道该数不是质数,所以无需再继续检查。
    • 最后,我们检查 isPrime 的值,以输出该数是否为质数。
  3. 保存文件(Ctrl+S 或 Cmd+S)。

  4. 在终端中编译修改后的程序:

    javac HelloJava.java

    如果没有编译错误,将会创建一个 HelloJava.class 文件。

  5. 运行编译后的程序:

    java HelloJava
  6. 程序会提示你输入一个正整数。输入一个数字(例如 7)并按回车键。程序会告诉你该数是否为质数。尝试输入不同的数字,如 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 * d' = n。这个另一个除数 d' 必定小于平方根(d' < sqrt(n))。因此,如果一个数除了 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 类型的值,所以我们将其转换为 int 类型,因为我们的循环计数器 i 是整数类型。我们将这个值存储在一个名为 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;:我们初始化 number 变量和一个 boolean 类型的标志 validInput
    • while (!validInput):这是一个 while 循环,只要 validInputfalse,循环就会继续执行。
    • 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 块中非常关键。它会消耗掉扫描器中的无效输入,防止程序陷入无限循环,一直尝试读取相同的无效输入。
  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 的循环来检查是否能整除。这种初始方法让我们对质数的定义及其算法实现有了基本的理解。

然后,我们探索了优化方法以提高质数检查的效率。这包括理解我们只需要检查到该数的平方根的除数,这显著减少了处理较大输入时所需的迭代次数。最后,我们通过处理负数和非整数输入来解决边界情况,使我们的质数检查函数更加健壮和完善。