素数计算器花费太多时间(JAVA)

时间:2015-09-05 20:11:52

标签: java primes

当我运行此代码以查找低于20的素数之和时,它可以正常工作,但是当试图找到低于250000的总和时,需要花费太多时间。已经至少20分钟了,而且还在运行。好像它没有用。我该如何解决?

class PrimeSummation {
    public static void main(String[] args) {
        int sum = 0;
        for(int i = 1; i < 2500000; i++) {
            int count = 0;
            for(int j = 1; j < i + 1; j++) {
                if((i%j) == 0) {
                    count++;
                }
            }
            if(count == 2) {
                sum += i;
            }
        }
        System.out.println(sum);
    }
}

3 个答案:

答案 0 :(得分:3)

跟踪以前发现的素数似乎有所帮助:

    BigInteger sum = BigInteger.ZERO;
    List<Integer> primes = new ArrayList<>();
    for(int i = 2; i < 2500000; i++) {
        boolean isPrime = true;
        for(int j = 0; j < primes.size() && primes.get(j)<= Math.sqrt(i); j++) {
            int p = primes.get(j);
            if((i%p) == 0) {
                isPrime=false;
                break;
            }
        }
        if(isPrime) {
            sum = sum.add(BigInteger.valueOf(i));
            primes.add(i);
        }
    }
    System.out.println(sum);

想出答案:

219697708195

答案 1 :(得分:3)

sum不能是int,因为答案为219697708195,而Integer.MAX_VALUE仅为2147483647。您必须改为使用longBigInteger

你的算法速度非常慢,因为每个2500000数字都是从头开始决定它是否是素数,以及你测试数字是否为素数的方法(尝试每个可能的因素) )效率不高。

以下代码在我的机器上产生大约十分之一秒的答案。

int num = 2500000;
long sum = 0;
boolean[] arr = new boolean[num];
for (int p = 2; p < num; p++) {
    if (!arr[p]) {
        sum += p;
        for (int k = p * 2; k < num; k += p)
            arr[k] = true;
    }
}
System.out.println(sum);

答案 2 :(得分:1)

如果您希望获得更好的效果来生成大量prime number,则应使用Sieve formula

您可以了解素数生成的Sieve_of_Eratosthenes公式。

根据Sieve_of_Eratosthenes

import java.util.*;

public class Sieve
{
    private BitSet sieve;

    private Sieve() {}

    private Sieve(int size) {
        sieve = new BitSet((size+1)/2);
    }

    private boolean is_composite(int k)
    {
        assert k >= 3 && (k % 2) == 1;
        return sieve.get((k-3)/2);
    }

    private void set_composite(int k)
    {
        assert k >= 3 && (k % 2) == 1;
        sieve.set((k-3)/2);
    }

    public static List<Integer> sieve_of_eratosthenes(int max)
    {
        Sieve sieve = new Sieve(max + 1); // +1 to include max itself
        for (int i = 3; i*i <= max; i += 2) {
            if (sieve.is_composite(i))
                continue;

            // We increment by 2*i to skip even multiples of i
            for (int multiple_i = i*i; multiple_i <= max; multiple_i += 2*i)
                sieve.set_composite(multiple_i);

        }
        List<Integer> primes = new ArrayList<Integer>();
        primes.add(2);
        for (int i = 3; i <= max; i += 2)
            if (!sieve.is_composite(i))
                primes.add(i);

        return primes;
    }
}

性能:

enter image description here