我正在尝试运行此代码来打印少于200万的所有素数的总和。这个循环永无止境。谁能告诉我代码有什么问题?它似乎适用于较小的数字。
public static void main(String[] args) {
long result = 1;
for(int i=0; i<2000000; i++) {
if(isPrime(i)) {
result+= i;
}
}
System.out.println(result);
}
private static boolean isPrime(long n) {
boolean result = false;
for(long i=2; i<(long)Math.sqrt(n); i++) {
if(n%i == 0) {
result = false;
break;
}
else result = true;
}
return result;
}
答案 0 :(得分:5)
在isPrime
中,您只是按2进行分区测试:
private static boolean isPrime(long n) {
boolean result = false;
for(long i=1; i<n/2; i++) {
if(n%2 == 0) {
result = false;
break;
}
else result = true;
}
return result;
}
它应该按每i
除以从2开始:
for(long i=2; i<n/2; i++) {
if(n%i == 0) {
...
实际上,在您当前的版本中,奇数n
将继续除以2到n/2
,而不是更快地停止。考虑n = 21.你将2从1除以1,而不是在第3步除以3并退出。
它不仅会提供不正确的结果,而且还需要比达到return
声明所需的时间更长的时间。
编辑:为了获得更快的结果,请查看此Erathostenes方法筛:
public static long sumOfPrimes(int n) {
long sum = 0;
boolean[] sieve = new boolean[n];
for(int i = 2; i < Math.sqrt(n); i++) {
if(!sieve[i]) {
for(int j = i * i; j < n; j += i) {
sieve[j] = true;
}
}
}
for(int i = 2; i < n; i++) {
if(!sieve[i]) {
sum += i;
}
}
return sum;
}
编辑#2 :发现新版本的一些错误。以下是更正后的内容:
private static boolean isPrime(long n) {
boolean result = false;
if(n == 2 || n == 3) return true;
for (long i = 2; i <= (long) Math.sqrt(n); i++) {
if (n % i == 0) {
result = false;
break;
} else
result = true;
}
System.out.println(n + " " + result);
return result;
}
答案 1 :(得分:2)
isPrime()
测试应该是:
if(n%i == 0) { ...
并且您需要从2
开始计数,而不是1
,因为除以1
时,每个数字的余数为零!
此外,无需经过Math.sqrt(n)
。
您应该将其更改为:
private static boolean isPrime(long n) {
long max = (long)Math.sqrt(n);
for (long i = 2; i < max; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
仅供参考,通过此更改,我在我的电脑上测试了该程序,并在1秒内完成,结果为143064094810
答案 2 :(得分:0)
天真isPrime
函数必须在每次运行时计算最多i
(或至少高达sqrt(i)
)的所有素数。确保你的isPrime函数缓存其结果!
答案 3 :(得分:0)
static boolean isPrime(int n) {
if (n == 1) return false;
for(int i = 2; i <= n/2; i++)
if(n % i == 0)
return false;
return true;
}
答案 4 :(得分:0)
以下是使用JOptionPane的Prime的完整程序,即Java GUI
import javax.swing.*;
public class ChkPrime {
public static void main(String[] args) throws NumberFormatException {
String str = JOptionPane.showInputDialog(null, "Enter any number: ","Input...", 3);
try {
int num = Integer.parseInt(str);
if (num == 1)
JOptionPane.showMessageDialog(null, "Your inputed no. " + num + " is not prime.","Error!", 0);
for(int i = 2; i <= Math.sqrt(num); i++) {
if(num % i == 0) {
JOptionPane.showMessageDialog(null, "Your inputed no. " + num + " is not prime.","Error!", 0);
System.exit(0);
}
}
JOptionPane.showMessageDialog(null, "Your inputed no. " + num + " is prime.","Yeh! Got it!", 1);
}
catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Please input numbers...","Error!", 0);
main(null);
}
}
}