对于Project Euler problem #10,我写了一个程序来查找2到2,000,000之间所有素数的总和。
我的代码适用于较小的值,如50或100,但当我尝试使用2,000,000时,它会返回一个太小的值141,675。
我认为这可能是因为答案太长而无法长时间使用,这就是我使用BigInteger的原因,但我已经知道这不是一个因素。我很感激任何想法。
public class ProblemTen {
/**
* Precondition: all the bits in the set are set to true
* This method uses the Sieve of Eratosthenes
* @param p the starting prime number
* @param b the BitSet array
* @param s the length of the original BitSet array
* @return BitSet with all the prime indexes set to true
*/
public static BitSet findPrimes(int p, BitSet b, int s) {
//System.out.println(b);
while (p*p < s) { // repeat until p^2 > size of the ORIGINAL set
for (int i = 0; i <= b.length(); i++) {
if (i%p == 0) { // if it's a multiple of p
b.set(i, false); // set it to false (not prime)
}
}
p = b.nextSetBit(p); // Make p = first bit that is set to true starting after the previous p index.
}
return b;
}
/**
* @param args
*/
public static void main(String[] args) {
int set = 2000000;
BitSet bits = new BitSet(set);
for (int i = 0; i < set; i++) {
bits.set(i); // set all bits to True; when you print only the true ones print out
}
BitSet primeBits = new BitSet(set);
primeBits = findPrimes(2, bits, set);
//System.out.println("List of primes: " + primeBits);
BigInteger sum = BigInteger.ZERO;
for (int j = 0; j <= primeBits.length(); j++) {
if (primeBits.get(j) == true ) {
sum = sum.add(BigInteger.valueOf(j));
}
}
System.out.println("Sum is: " + sum); // I get 142,913,687,247 which is 141,675 too small (142913828922)
}
}
答案 0 :(得分:2)
while (p*p < s) { // repeat until p^2 > size of the ORIGINAL set
for (int i = 0; i <= b.length(); i++) {
if (i%p == 0) { // if it's a multiple of p
b.set(i, false); // set it to false (not prime)
}
}
p = b.nextSetBit(p);
// Make p = first bit that is set to true starting after the previous p index.
}
将素数p
的所有倍数标记为复合,包括p
本身。所以只有大于极限平方根的素数才能保持无标记。
- 此方法使用Sieve of Eratosthenes
不,它没有。它使用试验部门。您将每个数字除以小于限制的平方根的所有素数,并检查余数是否为0。
循环应该是
for(int i = p*p; i < b.length; i += p)
b.set(i,false);
实施Eratosthenes筛选。
答案 1 :(得分:0)
for (int i = 0; i <= b.length(); i++)
将其更改为
for (int i = p+1; i <= b.length(); i++)
否则,您将删除小于2,000,000 ^ .5
的所有素数答案 2 :(得分:0)
你的解决方案不是 Eratosthenes的Sieve,它是试验部门;模运算符将它放弃。这是一个适当的Eratosthenes筛子的伪代码,它总结了它找到的素数:
function sumPrimes(n)
sum := 0
sieve := makeArray(2..n, True)
for p from 2 to n step 1
if sieve[p]
sum := sum + p
for i from p * p to n step p
sieve[i] := False
return sum
我会留给你将代码翻译成Java。如果您对素数编程感兴趣,我谦虚地在我的博客上推荐这个essay,其中包括Java中的Eratosthenes筛选。那里的代码也可以帮助你解决其他一些Project Euler问题。