一个质数程序,允许用户测试数字直到用户输入零。但是,在测试了 6 个数字后,它打印出错误的消息
a prime number program that allows the user to test numbers till the user enters zero. However, after testing 6 numbers, it prints incorrect message
一个质数程序,允许用户测试一个数是否为质数,直到用户输入零。然而,在测试了大约 6 个数字之后,它打印出错误的消息,就像它打印数字是一个非素数的素数一样,打印一个数字不是素数的素数。
package com.selfexercise.exercise;
/**
* Created by One on 2/15/2017.
*/
import java.util.Scanner;
public class PrimeNumbers {
public static void main(String[] args) {
int n;
boolean flag=true;
Scanner in = new Scanner(System.in);
for(;;) {
System.out.print("\nPlease enter a number : ");
n = in.nextInt();
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
flag = false;
break;
}
}
if (flag) {
System.out.println(n + " is a prime number");
} else {
System.out.println(n + " is not a prime number");
}
if(n==0)
break;
}
}
}
您在程序开始时声明 flag = true
。然后,一旦你找到一个因数,它就会被设置为 false
,所以你知道这个数字不是质数。
但是,当用户输入另一个数字时,flag
已经是false。每次从用户那里得到一个新号码时,您需要将它设置为 true
。
// no need to declare flag before the loop
for(;;) {
// initialise flag to true for each input number
boolean flag = true;
System.out.print("\nPlease enter a number : ");
n = in.nextInt();
...
if (flag) {
System.out.println(n + " is a prime number");
} else {
System.out.println(n + " is not a prime number");
}
flag = true;
希望这会有所帮助?一旦变量标志变为假,您的代码不允许任何指令将其重置为默认状态以供 for(;;) loop
中的下一次迭代使用
其他人已经指出了你的错误。我对您的代码还有其他一些评论。
首先,您的素数检查系统有效,但效率低下。 Eratosthenes 筛法比您正在使用的 Trial Division 方法快得多。即使只是试用除法,您的代码也可以通过使用 sqrt(n) 的限制代替 n / 2
并分别处理偶数来加快速度。通过将质数检查放入单独的布尔方法来保持主代码更简洁也是一种传统做法:
boolean isPrime(int num) {
// Low and negative numbers.
if (num < 2) {
return false;
}
// Even numbers.
if (num % 2 == 0) {
// Two is the only even prime.
return num == 2;
}
// Odd numbers.
for (int i = 3; i * i <= num; i += 2) {
if (num % i == 0) {
return false;
}
}
return true;
} // end isPrime()
只要您需要检查素数,就可以重复使用该方法。
其次,您在主代码中对循环的处理似乎很笨拙,例如使用 break
退出。假设您重复读取用户的输入直到输入 0,那么 do ... while
循环最适合:
public static void main(String[] args) {
int n;
Scanner in = new Scanner(System.in);
do {
System.out.print("\nPlease enter a number or 0 to quit : ");
n = in.nextInt();
if (isPrime(n)) {
System.out.println(n + " is a prime number.");
} else {
System.out.println(n + " is not a prime number.");
}
} while (n != 0);
}
这使用了之前的 isPrime()
方法,它替换了您的 flag
变量。请注意,使用 do ... while
循环会从循环中消除显式的 break
。这是因为这种循环风格比您之前使用的 for
循环更适合您正在做的事情。如果您事先知道要测试多少个数字,for
循环会更好。
一个质数程序,允许用户测试一个数是否为质数,直到用户输入零。然而,在测试了大约 6 个数字之后,它打印出错误的消息,就像它打印数字是一个非素数的素数一样,打印一个数字不是素数的素数。
package com.selfexercise.exercise;
/**
* Created by One on 2/15/2017.
*/
import java.util.Scanner;
public class PrimeNumbers {
public static void main(String[] args) {
int n;
boolean flag=true;
Scanner in = new Scanner(System.in);
for(;;) {
System.out.print("\nPlease enter a number : ");
n = in.nextInt();
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
flag = false;
break;
}
}
if (flag) {
System.out.println(n + " is a prime number");
} else {
System.out.println(n + " is not a prime number");
}
if(n==0)
break;
}
}
}
您在程序开始时声明 flag = true
。然后,一旦你找到一个因数,它就会被设置为 false
,所以你知道这个数字不是质数。
但是,当用户输入另一个数字时,flag
已经是false。每次从用户那里得到一个新号码时,您需要将它设置为 true
。
// no need to declare flag before the loop
for(;;) {
// initialise flag to true for each input number
boolean flag = true;
System.out.print("\nPlease enter a number : ");
n = in.nextInt();
...
if (flag) {
System.out.println(n + " is a prime number");
} else {
System.out.println(n + " is not a prime number");
}
flag = true;
希望这会有所帮助?一旦变量标志变为假,您的代码不允许任何指令将其重置为默认状态以供 for(;;) loop
中的下一次迭代使用其他人已经指出了你的错误。我对您的代码还有其他一些评论。
首先,您的素数检查系统有效,但效率低下。 Eratosthenes 筛法比您正在使用的 Trial Division 方法快得多。即使只是试用除法,您的代码也可以通过使用 sqrt(n) 的限制代替 n / 2
并分别处理偶数来加快速度。通过将质数检查放入单独的布尔方法来保持主代码更简洁也是一种传统做法:
boolean isPrime(int num) {
// Low and negative numbers.
if (num < 2) {
return false;
}
// Even numbers.
if (num % 2 == 0) {
// Two is the only even prime.
return num == 2;
}
// Odd numbers.
for (int i = 3; i * i <= num; i += 2) {
if (num % i == 0) {
return false;
}
}
return true;
} // end isPrime()
只要您需要检查素数,就可以重复使用该方法。
其次,您在主代码中对循环的处理似乎很笨拙,例如使用 break
退出。假设您重复读取用户的输入直到输入 0,那么 do ... while
循环最适合:
public static void main(String[] args) {
int n;
Scanner in = new Scanner(System.in);
do {
System.out.print("\nPlease enter a number or 0 to quit : ");
n = in.nextInt();
if (isPrime(n)) {
System.out.println(n + " is a prime number.");
} else {
System.out.println(n + " is not a prime number.");
}
} while (n != 0);
}
这使用了之前的 isPrime()
方法,它替换了您的 flag
变量。请注意,使用 do ... while
循环会从循环中消除显式的 break
。这是因为这种循环风格比您之前使用的 for
循环更适合您正在做的事情。如果您事先知道要测试多少个数字,for
循环会更好。