我正试图找到素数之和< 2,000,000。这是我在Java中的解决方案,但我似乎无法得到正确的答案。请对可能出现的错误提供一些意见,并对该代码的一般建议表示赞赏。
打印'sum'给出:1308111344,这是不正确的。
编辑: 谢谢你的帮助。将int更改为long和< to< =并且它完美无缺,除了是找到素数的低效方式之外:)
/*
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
*/
class Helper{
public void run(){
Integer sum = 0;
for(int i = 2; i < 2000000; i++){
if(isPrime(i))
sum += i;
}
System.out.println(sum);
}
private boolean isPrime(int nr){
if(nr == 2)
return true;
else if(nr == 1)
return false;
if(nr % 2 == 0)
return false;
for(int i = 3; i < Math.sqrt(nr); i += 2){
if(nr % i == 0)
return false;
}
return true;
}
}
class Problem{
public static void main(String[] args){
Helper p = new Helper();
p.run();
}
}
答案 0 :(得分:7)
结果太大而无法放入整数,因此您得到overflow。请尝试使用BigInteger或long。在这种情况下,长就足够了。
答案 1 :(得分:6)
你将那些只能被平方根整除的数字(如25)视为素数。而不是i < Math.sqrt(nr)
尝试i <= Math.sqrt(nr)
。
顺便说一句,这是找到素数的一种非常低效的方法。
答案 2 :(得分:3)
你的isPrime不适合广场。 isPrime(9)返回true。
答案 3 :(得分:1)
如前所述,错误有两个:
int
不足以容纳该金额。您应该使用long
<
而不是<=
,而且这是一个错误的守护周期除此之外你正在做的事情是非常低效的,如果没有深入这类算法(比如 Miller-Rabin 测试),我建议你去看看{{3一种非常古老的方法,教导如何以简单的方式处理复杂的问题,通过记忆的权衡来提高优雅和效率。
它真的很敏锐:它会跟踪每个素数的boolean
值,如果该数字是素数,则会断言。然后从第一个素数开始,它排除了通过乘以它正在分析另一个数的素数而获得的所有连续数。更多的是,它需要检查的数量越少(因为它已经排除了它们)
代码很简单(只是动态编写,没有检查):
boolean[] numbers = new boolean[2000000];
long sum = 0;
for (int i = 0; i < numbers.length; ++i)
numbers[i] = true;
for (int i = 2; i < numbers.length; ++i)
if (!numbers[i])
continue;
else {
int j = i + i;
while (j < 2000000) {
numbers[j] = false;
j += i;
}
}
for (int i = 2; i < 2000000; ++i)
sum += numbers[i] ? i : 0;
System.out.println(sum);
当然这种方法仍然不适合高数字(因为它必须找到所有以前的素数而且因为记忆)但是这是初学者思考问题的好例子。
答案 4 :(得分:1)
有效地使用Sieve of Eratosthenes,我解决了问题,这是我的代码
public class SumOfPrime {
static void findSum()
{
long i=3;
long sum=0;
int count=0;
boolean[] array = new boolean[2000000];
for(long j=0;j<array.length;j++)
{
if((j&1)==0)
array[(int)j]=false;
else
array[(int)j]=true;
}
array[1]=false;
array[2]=true;
for(;i<2000000;i+=2)
{
if(array[(int)i] & isPrime(i))
{
array[(int)i]=true;
//Sieve of Eratosthenes
for(long j=i+i;j<array.length;j+=i)
array[(int)j]=false;
}
}
for(int j=0;j<array.length;j++)
{
if(array[j])
{
//System.out.println(j);
count++;
sum+=j;
}
}
System.out.println("Sum="+sum +" Count="+count);
}
public static boolean isPrime(long num)
{
boolean flag=false;
long i=3;
long limit=(long)Math.sqrt(num);
for(;i<limit && !(flag);i+=2)
{
if(num%i==0)
{
flag=false;
break;
}
}
if(i>=limit)
flag=true;
return flag;
}
public static void main(String args[])
{
long start=System.currentTimeMillis();
findSum();
long end=System.currentTimeMillis();
System.out.println("Time for execution="+(end-start)+"ms");
}
}
,输出
Sum=142913828922 Count=148933
Time for execution=2360ms
如果您有疑问,请告诉
答案 5 :(得分:0)
这是我的解决方案
public class ProjectEuler {
public static boolean isPrime(int i) {
if (i < 2) {
return false;
} else if (i % 2 == 0 && i != 2) {
return false;
} else {
for (int j = 3; j <= Math.sqrt(i); j = j + 2) {
if (i % j == 0) {
return false;
}
}
return true;
}
}
public static long sumOfAllPrime(int number){
long sum = 2;
for (int i = 3; i <= number; i += 2) {
if (isPrime(i)) {
sum += i;
}
}
return sum;
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(sumOfAllPrime(2000000));
}
}