Java程序查找低于2,000,000的所有素数的总和(Project Euler)

时间:2012-06-07 21:35:30

标签: java

我试图解决Project Euler的10个 th 问题,但由于某种原因,我无法做到正确。我是编程和Java的新手,所以我无法理解为什么它不起作用。问题的关键是要找到2,000,000以下所有素数的总和。

/*  The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.

    Find the sum of all the primes below two million.
*/  

public static void main(String[] args){

    long n = 1;
    long sum = 0;
    long limit;

    System.out.println("Enter the limit of n: ");
    limit = TextIO.getlnLong(); //TextIO is another input method
    while (limit <= 0){
        System.out.println("Enter the limit of n (must be positive): ");
        limit = TextIO.getlnLong();

    }       

    while (n < limit){ 
        n++;
        if (n % 2 != 0 && n % 3 != 0 && n % 5 != 0 && n % 7 != 0 && n != 1 || n == 2 || n == 3 || n == 5 || n == 7){ //this is my prime checking method, might be flawed

            sum = sum + n;  
            System.out.println(+sum);
        } //end if

    }//end while

    System.out.println("The sum of the primes below 2,000,000 is: " +sum);

} //end of main

5 个答案:

答案 0 :(得分:4)

对于高效的素数检查方法,请阅读Sieve of Eratosthenes

答案 1 :(得分:2)

你的主要方法被打破了。如果数字在2和数字的平方根之间没有任何除数,则数字为素数。 13 * 13会通过你的主要检查功能。

for i to sqrt(n):
   if(n % i == 0):
       OH NO NOT PRIME DO SOMETHING HERE?
if something is prime
   add some stuff

答案 2 :(得分:1)

以下是2个比普通解决方案更好的解决方案:

1)迭代奇数(唯一偶数素数已经在总和中)并检查它们是否为素数:

private static boolean isOddPrime(int x) {
    for ( int i = 3 ; i*i <= x ; i+=2 ){ 
        if ( x % i == 0 ) {
            return false;
        }
    }
    return true;
}

private static void sumOfPrimes1(int n) {       
    long sum = 2;
    for ( int i = 3 ; i < n ; i+=2 ) {
        if ( isOddPrime(i) ) {
            sum+=i;
        }
    }
    System.out.println(sum); 
}

2)使用 Eratosthenes筛选

private static void sumOfPrimes2(int n) {
    boolean notPrimes[] = new boolean[n];   // default = false
    for ( int i = 2 ; i*i < n ; i++ ) {
        if ( !notPrimes[i] ) {
            for ( int j = i*i ; j < n ; j+=i ){
                notPrimes[j] = true;
            }
        }
    }
    long sum = 2 ;
    for ( int i = 3 ; i < n ; i+=2 ) {
        if ( !notPrimes[i] ) {
            sum+=i;
        }
    }
    System.out.println(sum);
}

我使用“notPrimes”(复合)代替“primes”作为数组,只是为了利用Java中的默认布尔值为false这一事实。

<强>性能

n           |    2000000        8000000       16000000
------------+-------------------------------------------
Solution 1  |    1309 ms        8574 ms       22757 ms
Solution 2  |    119 ms         696 ms        1624 ms

答案 3 :(得分:0)

http://www.counton.org/explorer/primes/checking-if-a-number-is-prime/

检查数字N是一个质数的捷径是,我们不必尝试将每个数字从2依次转换为N(2、3、4、5、6…..N-1)来查看任何一个他们正好除以N。

exp:由于3是18的因数,并且18/3 = 6,则18 = 3x6。我们只需要测试较小的数字3,看它是否是18的因数而不是6。类似地,5是20的因数,而20 = 5x4,因此我们只需要测试较小的数字4。但是,如果我们不知道数字的因素怎么办?因此,测试一个数字是否为质数意味着我们只需要测试“较小”的因素。但是,较小的因素在哪里停止而较大的因素在哪里开始呢?这里的原理是: 假设一个数是N的因数,并且它小于数N的平方根。那么第二个因数必须大于平方根。 我们可以通过上面的示例看到这一点:对于18,我们只需要测试数字,直到18的平方根即4.243,即最多4!这比测试最多17个数字要快得多! 对于25,我们需要测试不超过25的平方根(即5)的数字。 对于37,我们只需要增加到6(因为6x6 = 36,所以37的平方根只会大一点)。

public static void main(String[] args) {
    long sum = 0;
    for (int i = 2; i < 2000000; i++) {
        if (isPrime(i)) {
            sum += i;
        }
    }
    System.out.println(sum);
}

// check if a number is prime
private static boolean isPrime(int number) {
    int sqrt = (int) Math.sqrt(number);
    boolean isPrime = true;

   // test up to square root of the number
   for (int i = 2; i <= sqrt; i++) {
        if (number % i == 0) {
            isPrime = false;
            break;
        }
    }
    return isPrime;
}

答案 4 :(得分:-4)

public static void main(String args[])
{
  long n = 1;
  long sum = 0;
  long limit=Integer.parseInt(args[0]);

  while (n < limit)
  {
    n++;
    if(n % 2 != 0 && n % 3 != 0 && n % 5 != 0 && n % 7 != 0 && n != 1 || n == 2 || n == 3 || n == 5 || n == 7)
    {
      sum = sum + n;
    }
  }


    System.out.println("The sum of the prime numbers = " +sum);
 }