介绍
在这个实验中,你将学习如何在 Java 中检查一个数是否为质数。我们将从实现一个基本的循环来判断质数开始。
接下来,我们将通过利用该数的平方根来优化质数检查过程。最后,我们将改进代码,使其能够妥善处理负数和非整数输入。
实现基本的质数检查循环
在这一步中,我们将编写一个 Java 程序,使用基本的循环来检查给定的数是否为质数。质数是一个大于 1 的自然数,除了 1 和它自身外,不能被其他正整数整除。
如果
HelloJava.java文件尚未在 WebIDE 编辑器中打开,请打开它。将文件的全部内容替换为以下代码:
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。我们从 2 开始检查除数,因为 1 总是一个除数,而我们要找的是除 1 和该数本身之外的除数。if (number % i == 0):在循环内部,这行代码检查number是否能被i整除(即除法的余数为 0)。如果可以,这意味着我们找到了除 1 和该数本身之外的除数。isPrime = false;:如果找到了除数,我们将isPrime设置为false。break;:这个语句会立即退出for循环。一旦我们找到一个除数,就知道该数不是质数,所以无需再继续检查。- 最后,我们检查
isPrime的值,以输出该数是否为质数。
- 我们仍然使用
保存文件(Ctrl+S 或 Cmd+S)。
在终端中编译修改后的程序:
javac HelloJava.java如果没有编译错误,将会创建一个
HelloJava.class文件。运行编译后的程序:
java HelloJava程序会提示你输入一个正整数。输入一个数字(例如 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 有一个大于其平方根的除数 d(d > sqrt(n)),那么必然存在另一个除数 d',使得 d * d' = n。这个另一个除数 d' 必定小于平方根(d' < sqrt(n))。因此,如果一个数除了 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类型的值,所以我们将其转换为int类型,因为我们的循环计数器i是整数类型。我们将这个值存储在一个名为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 的循环来检查是否能整除。这种初始方法让我们对质数的定义及其算法实现有了基本的理解。
然后,我们探索了优化方法以提高质数检查的效率。这包括理解我们只需要检查到该数的平方根的除数,这显著减少了处理较大输入时所需的迭代次数。最后,我们通过处理负数和非整数输入来解决边界情况,使我们的质数检查函数更加健壮和完善。



