更有效的方法呢?

时间:2013-03-18 23:43:23

标签: java sum factors

我想知道是否有更有效的方法来运行这个程序?

它适用于较低的数字,但随着时间的增加,时间也会增加 - 指数级。所以像1000000这样的数字永远需要

import java.util.*;

public class SumOfPrimes {

public static void main(String args[]) {
    Scanner in = new Scanner(System.in);
    long number = 0;

    System.out.println("This program outputs the sum of the primes of a given number.");
    System.out.print("Please enter a number: ");
    number = in.nextLong();

    System.out.println("The sum of the primes below "+number+" is: "+sumOfPrimes(number));
}

public static long sumOfPrimes(long n){
    long currentNum = 2;
    long sum = 0;
    if (n > 2){
        sum = sum + 2;
    }

    while (currentNum <= n) {
        if (currentNum % 2 != 0 && isPrime(currentNum)) {
            sum = sum + currentNum;
        }
        currentNum++;
    }
return sum;
}

public static boolean isPrime(long currentNum){
    boolean primeNumber = true;

    for (long test = 2; test < currentNum; test++) {
        if ((currentNum % test) == 0){
            primeNumber = false;
        }
    }

return primeNumber;
}
}

4 个答案:

答案 0 :(得分:5)

有更好的寻找算法,但作为一个快速修复,你只需要通过当前数字的平方根测试因子,因为如果你找到一个高于平方根的因子,那么你应该找到一个因素低于平方根。

long stop = (long) Math.sqrt(currentNum);
for (long test = 2; test <= stop ; test++) {

此外,如果您找到了一个因子并且因此证明了数字合成,则跳出循环并返回false

如果需要更高的效率,您可以实施Sieve of Eratosthenes,这样您只能检查本身可能的因素。

答案 1 :(得分:1)

每次找到一个素数时,你真的应该存储一组素数,所以你每次都要避免除以所有数字。

这件事:currentNum % 2 != 0可以写成currentNum & 1

你的算法也错了,试着给3输入。

答案 2 :(得分:1)

使用Eratosthenes Sievie:http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes你会在O(n log n log n)中找到所有数量低于给定数字的素数,你需要在整个表格中找到一次。

答案 3 :(得分:0)

我写了一个。我不能确定一切都是对的。我已经在我的机器上测试了1000000,它只花了31毫秒。 内存需要:1000000 * 1bytes = 1mb

public class FindPrime {

/**
 * @param args
 */
public static void main(String[] args) {
    long begin=System.currentTimeMillis();
    System.out.println(findPrime(1000000));

    System.out.println("cost time="+(System.currentTimeMillis()-begin)+"ms");

}

public static long findPrime(int max){
    boolean data[]=new boolean[max+1];
    long sum=0;
    int stop=(int) Math.sqrt(max);
    for(int i=2;i<=stop;i++){
        if(data[i]==false){
            sum+=i;

            int index=i+i;
            while(index<=max){
                data[index]=true;
                index=index+i;
            }
            //System.out.println(i);
        }
    }

    stop=stop+1;

    for(;stop<=max;stop++){
        if(data[stop]==false){
            sum+=stop;
            //System.out.println(stop);
        }
    }

    return sum;
}

}