缓慢计算大数据集的素数之和

时间:2017-10-31 07:25:59

标签: java

对于非常大的第n个项,计算素数之和的程序非常慢。请问如何优化程序的处理时间?最快的程序将受到赞赏,以及我的大型数据集的速度慢的原因。感谢。

这是Java程序:

 public class SumOfPrimes {
    public static void main(String[] args) {
        primeNumber(2000000);
    }

    public static void primeNumber(int nth) {
        int counter = 0, i = 2;
        while(i>=2) {
            if(isPrime(i)) {
                counter += i;
            }
            i++;
            if(i == nth) {
                break;
            }
        }
        System.out.println(counter);
    }

    public static boolean isPrime(int n) {
        boolean prime = true;
        int i;
        for(i= 2; i < n; i++) {
            if (n % i == 0) {
                prime = false;
                for (int j = 3; j * j < n; j += 2) {
                    if (n % j == 0) prime = false;
                }
            }
        }
        return prime;
    }

 }

7 个答案:

答案 0 :(得分:8)

嗯,目前还不清楚为什么你的isPrime内有for循环。删除它将节省很多时间。

此外,一旦您发现n不是素数,您应立即返回。要么突破循环,要么只返回false

另一个优化是在i < n之前不测试所有数字。它足以测试到i * i <= n

public static boolean isPrime(int n) {
    int i;
    for(i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

答案 1 :(得分:4)

记住你找到的素数,只测试它们。

删除内循环。

测试2,3,然后是所有赔率。

像...一样的东西。

public boolean isPrime( ArrayList<Long> primes, long n ){
    for( Long t : primes ){
        if( n % t == 0 ){
            return false;
        }
        if( t * t > n )return true;
    }
    return true;
}
public void sumOfPrimes()
{

    ArrayList<Long> primes = new ArrayList<Long>();
    long n;
    double count = 0;
    for( n = 2; n < 2000000; n++ ){
        if( isPrime( primes, n ) ){
            primes.add( n );
            count += n;
        }
    }
}

答案 2 :(得分:3)

这应该是你的isPrime功能 -

bool isPrime (int number) { 
    if (number < 2) return false;
    if (number == 2) return true;
    if (number % 2 == 0) return false;
    for (int i=3; (i*i) <= number; i+=2) {
        if (number % i == 0 ) return false;
    }
    return true;
}

答案 3 :(得分:0)

利用Lambda的强大功能进行动态功能参考和流,以通过内置过滤条件优化性能。

public static boolean isPrime(final int number) {
    return IntStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0);
}

答案 4 :(得分:0)

将上述问题的所有答案汇总在一起,我的程序已经重新编写,对于非常大的数据集来说速度要快得多。

 public class SumOfPrimes {
    public static void main(String[] args) {
        primeNumber(2000000);
    }

    public static void primeNumber(int nth) {
        int i = 2;
        long  counter = 0;
        while(i>=2) {
            if(isPrime(i)) {
                counter += i;
            }
            i++;
            if(i == nth) {
                break;
            }
        }
        System.out.println(counter);
    }

public static boolean isPrime (int n) {
    if (n < 2) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;
    for (int i=3; (i*i) <= n; i+=2) {
        if (n % i == 0 ) return false;
    }
    return true;
}

}

@ aega的isPrime函数解决方案就行了。现在可以计算不到2秒的200万个数据集。

答案 5 :(得分:0)

我们不需要从1到n进行测试,甚至3到n / 2或3到sqrt(n)对于测试更大的数字也是太多了。

为了进行最少的测试,我们只能测试n之前已经找到的最高为sqrt(n)的素数,就像mksteve所提到的那样。

static List<Integer> primes = new ArrayList<>();

static boolean isPrime (int number) { 
    if (number < 2) return false;
    if (number == 2) return true;
    if (number % 2 == 0) return false;

    int limit = (int) Math.sqrt(number);

    for (i : primes) {
        if (i > limit) break;
        if (number % i == 0 ) return false;
    }
    return true;
}

public static void primeNumber(int nth) {
    int i = 2;
    long  counter = 0;
    while(i <= nth) {
        if(isPrime(i)) {
            counter += i;
            primes.add(i);
        }
        i++;
    }
    System.out.println(counter);
}

答案 6 :(得分:0)

更快的程序是将生成的素数存储在数组中,并仅使用这些元素进行可分性检查。迭代次数将大幅减少。在这里有自学的元素。

我现在没有时间。但是,当我有空时,会写一个java代码来实现它。