欧拉项目
问题10:Summation of primes
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
分析
这道题目是要求出2000000所有素数的和,首先想到是判断每一个数是否为素数,判断过程用试除法,但是如果数很大的话,会有很多的试除过程,所以是否可以减少或者降低试除的数量。
显然偶数不是素数,剩下所有的奇数包括素数和素数的倍数,所以只要能把素数的倍数排除出去,那么 剩下的就是素数了。
因为2也是一个素数,所以一个数如果不能被小于它的素数整除,那么他就是一个素数,然后可以再优化一下,只需要试除小于每个数的平方根的素数。
解决方案(Java)
package Problem10;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class PrimeSum {
//save the basic prime(2,3,5,7)
private final List<Integer> baseDivisor = new LinkedList<Integer>();
//save the prime without basic prime
private final List<Integer> prime = new LinkedList<Integer>();
private long sum = 0;
private int count = 0;
private final int MAX_NUMBER = 2000000;
public static void main(String[] args){
PrimeSum primeSum = new PrimeSum();
long startTime = System.currentTimeMillis();
/**
* Initialize
* add base prime 2 3 5 7 to list which called baseDivisor.
*/
primeSum.init();
/**
* check every number is a prime or not below the MAX_NUMBER
* The strategy have two steps
* 1.Every number divide numbers of baseDivisor(2 3 5 7)
* if can be divided with no remainder, this number is not a prime,
* if has remainder, this number is a prime, and then add this number to the prime list.
* 2.If step 1 not found this number is a prime,
* Continue to divide numbers of prime list which was added before as a prime.
* if has remainder, this number is a prime, and then add this number to the prime list.
* if can be divided with no remainder, it proof that this number is not a prime and go to next number.
*
* Note: the baseDivisor and prime list is a Linked List from first-in to first-out.
*/
primeSum.compute();
long endTime = System.currentTimeMillis();
System.out.println("Time: "+(endTime-startTime));
//output prime infomations.
primeSum.print();
}
private void init(){
baseDivisor.add(2);
baseDivisor.add(3);
baseDivisor.add(5);
baseDivisor.add(7);
sum = 2+3+5+7;
}
private void compute(){
for(int i=10;i<MAX_NUMBER;i++){
if(divisionBaseDivisor(i))continue;
if(divisionPrime(i))continue;
prime.add(i);
sum += i;
count++;
}
}
private boolean divisionPrime(int num){
return divisionDivisor(num,num,prime);
}
private boolean divisionBaseDivisor(int num){
return divisionDivisor(num,num,baseDivisor);
}
private boolean divisionDivisor(int maxFactor, int num, List<Integer> list){
boolean rtn = false;
maxFactor = (int)Math.sqrt(num);
Iterator<Integer> iter = list.iterator();
while(iter.hasNext()){
int divisor = iter.next();
if(divisor > maxFactor){
break;
}
if(num%divisor==0){
rtn = true;
break;
}
}
return rtn;
}
private void print(){
StringBuffer sb = new StringBuffer();
Iterator<Integer> basePrimeIter = baseDivisor.iterator();
while(basePrimeIter.hasNext()){
sb.append(basePrimeIter.next()+",");
}
Iterator<Integer> primeIter = prime.iterator();
while(primeIter.hasNext()){
sb.append(primeIter.next()+",");
}
// System.out.println(sb.toString());
System.out.println("The Count is: "+count);
System.out.println("The sum is: "+sum);
}
}
结果
Time: 200ms (3.40GHz双核 8G内存)
The Count is: 148929
The sum is: 142913828922