Problem 10

欧拉项目

问题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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值