写段代码验证哥德巴赫猜想之一:求给定范围的素数。

今天有位朋友去面试,一道题是“写段代码验证哥德巴赫猜想”,觉得很有意思,因为其中涉及到刚接触计算机时搞过的求素数算法,在记忆中,为了提高效率(用空间换时间),应该是保留已求得的素数,然后在判断N的时候,只需用N去依次试除所有不大于N平方根的已知质数,而勿需遍历小于N的所有(奇)数。
按上述思路编制的Primes类如下,可做为“验证哥德巴赫猜想”的辅助类(因为这个需求,所以该类的generate()方法可以按需要计算出所需的素数)。
这个求素数的算法速度很不错,在我赛扬2.0的机器上,大约在1.5秒就可以算出所有小于一百万的素数,共78,498个。
#pragma once
#include <vector>
#include <ostream>    // for ostream & operator << ()
#include <cmath>    // for sqrt()

class Primes {
public:
    Primes() {
        primes_.push_back(2);
        primes_.push_back(3);
    }
    //生成不小于maxValue的所有质数
    void generate(int maxValue) {
        if (maxValue <= getMaxPrime())
            return;
        for (int v=getMaxPrime()+2; v<=maxValue; v+=2) {
            int sqrtV = static_cast<int>(sqrt(static_cast<double>(v)));
            bool isPrime = true;
            for (size_t i=0; i<primes_.size() && primes_[i]<=sqrtV; ++i) {
                if (0==(v % primes_[i])) {
                    isPrime = false;
                    break;
                }
            }
            if (isPrime)
                primes_.push_back(v);
        }
    }
    //取已生成的最大质数
    int getMaxPrime() const { return primes_[primes_.size()-1]; }
    //取已生成的质数个数
    size_t getCount() const { return primes_.size(); }
    //取已生成质数中的指定序号项的质数
    int operator[](int index) const { return primes_[index]; }
    //判断给定数是不是质数
    bool isPrime(int value) const {
        if (value<primes_[0] || (value!=2 && 0==(value % 2)) || value>getMaxPrime())
            return false;
        //用二分法在已知质数中查找
        size_t low=0, high=primes_.size()-1;
        while (low<=high) {
            size_t midd = (low + high) / 2;
            int middPrime = getValue(midd);
            if (value==middPrime)
                return true;
            if (value<middPrime)
                high = midd - 1;
            else
                low = midd + 1;
        }
        return false;
    }
   
    //测试用,将生成的所有质数输出到流中
    friend std::ostream & operator << (std::ostream & os, const Primes & right) {
        for (size_t i=0; i<right.primes_.size(); ++i)
            os << right.primes_[i] << "/t";
        os << std::endl;
        return os;
    }

private:
    std::vector<int> primes_;
};
网上有段FLASH演示二分查找,很有意思:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值