简介
在这个实验中,你将学习如何在 Java 中检查一个数是否为质数。我们将从实现一个基本的循环来判断质数开始。
接下来,我们将通过利用该数的平方根来优化质数检查过程。最后,我们将改进代码,使其能够妥善处理负数和非整数输入。
在这个实验中,你将学习如何在 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
现在,尝试输入不同类型的内容:
观察程序如何处理这些不同的输入,它会提示你输入有效的正整数,直到你输入为止。
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 的循环来检查是否能整除。这种初始方法让我们对质数的定义及其算法实现有了基本的理解。
然后,我们探索了优化方法以提高质数检查的效率。这包括理解我们只需要检查到该数的平方根的除数,这显著减少了处理较大输入时所需的迭代次数。最后,我们通过处理负数和非整数输入来解决边界情况,使我们的质数检查函数更加健壮和完善。