求100亿以内的素数

来源:互联网 发布:python装饰器常见问题 编辑:程序博客网 时间:2024/04/29 18:26
#include <iostream>
#include<cmath>
#include <Windows.h>

using namespace std;

//自定义数据结构
typedef unsigned __int64 myInt;
typedef unsigned long myLong;

//首先判断1M以内的素数
const size_t primeSize=0x100000;//1M大小
myLong g_PrimeLength = 0;
myLong *g_pPrime=NULL;//存放所有的素数

//获得数据的索引
inline size_t GetIndex(myLong n)
{
    return (n-3)>>1;
}

//剔除prime的倍数
void fliter(myLong *pDataBuf,myLong prime)
{
    myLong maxTimes=primeSize/prime;
    for (myLong i=3;i<maxTimes;i+=2)
    {
        pDataBuf[GetIndex(i*prime)]=0;
    }
}

//求得此范围内的所有素数
void InitBasePrime()
{
    if (g_PrimeLength || g_pPrime)
    {
        return;
    }
    myLong* pDataBuf=new myLong[primeSize/2+1];//初始化数组大小
   
    //存储所有可能的奇数中的素数
    for (myLong i=0;i<primeSize/2;i++)
    {
        pDataBuf[i]=2*i+3;
    }
    //获得判断的最大上限
    myLong max=(myLong)sqrt((float)primeSize+1);
    max=GetIndex(max);
    //剔除其中的素数的倍数
    for (myLong i=0;i<max;i++)
    {
        if (pDataBuf[i])
        {
            fliter(pDataBuf,pDataBuf[i]);//将所有pDataBuf[i]的倍数剔除
        }
    }
    myLong* prime=new myLong[primeSize/2+1];
    myLong index=0;
    for (myLong i=0;i<primeSize/2+1;i++)
    {
        if (pDataBuf[i])
        {
            prime[index++]=pDataBuf[i];
        }
    }
    g_PrimeLength=index;
    g_pPrime=new myLong[g_PrimeLength+1];
    for (myLong i=0;i<g_PrimeLength;i++)
    {
        g_pPrime[i]=prime[i];
    }
    delete prime;
    delete pDataBuf;
}

//分段处理以后的数据
const size_t DataBufLength=0x100000/2;
const size_t Segement=0x1000-1;
class GenF1MTo4G
{
protected:
    myLong *m_pDataBuf;
    myLong *m_pTmpBuf;
public:
    GenF1MTo4G()
    {
        m_pDataBuf = new myLong[DataBufLength+1];
        m_pTmpBuf = new myLong[DataBufLength+1];
    }
    virtual ~GenF1MTo4G()
    {
        delete[]m_pDataBuf;
        delete[]m_pTmpBuf;
    }
    void GenPrimProcess()
    {
        for (myLong i=1;i<Segement;i++)
        {
            genPrimeOnce(i);
        }
    }
protected:
    void genPrimeOnce(myLong seg)
    {
        //求出该段的初始值
        myLong Base=0x100000*seg-1;
        cout<<"Process :"<<Base<<endl;
        InitBuf(Base,DataBufLength);
        filterPrime();
    }

    void InitBuf(myLong base,myLong len)
    {
        //得到这一段的所有奇数
        for(myLong i=0;i<len;i++)
            m_pDataBuf[i]=base+i*2;
    }
    void filterPrime()
    {
        for (myLong i=0;i<g_PrimeLength;i++)
        {
            if (!fliterOnce(g_pPrime[i]))
            {
                break;
            }
        }
    }
    bool fliterOnce(myLong prime)
    {
        myLong base=this->m_pDataBuf[0];
        myLong min=(base-1)/prime+1;
        myLong max=this->m_pDataBuf[DataBufLength-1]/prime;
        if (min<3)
        {
            return false;
        }
        for (;min<=max;min++)
        {
            this->m_pDataBuf[(prime-base>>1)]==0;
        }
        return true;
    }
};

//每段内的数个数
const myLong DataBufLength1=0x100000/2;
const myLong Segement1=10*1024;

class GenF4GTO10G
{
protected:
    myLong* m_pDataBuf;
    myLong* m_TmpBuf;
    myLong  m_Seg;
public:
    GenF4GTO10G():m_Seg(4*1024)
    {
        m_pDataBuf=new myLong[DataBufLength1+1];
        m_TmpBuf=new myLong[DataBufLength1+1];
    }

    virtual ~GenF4GTO10G()
    {
        delete[]m_pDataBuf;
        delete[]m_TmpBuf;
    }
    void GenPrimeProcess()
    {
        while (m_Seg<Segement1)
        {
            GenPrimeOnce();
            ++m_Seg;
        }
    }

protected:
    void GenPrimeOnce()
    {
        cout<<"Process:"<<m_Seg<<"M"<<endl;
        InitBuf(DataBufLength1);
        FilterPrime();
    }
    //初始化奇数
    void InitBuf(myLong len)
    {
        for (myLong i=0;i<len;i++)
        {
            m_pDataBuf[i]=2*i+1;
        }
    }
    void FilterPrime()
    {
        for (myLong i=0;i<g_PrimeLength;i++)
        {
            if (!FilterOnce(g_pPrime[i]))
            {
                break;
            }
        }
    }

    bool FilterOnce(myLong prime)
    {
        myInt base=myInt(this->m_Seg)*myInt(0x100000);
        myInt min=(base-1)/prime+1;
        myInt max=(base+m_pDataBuf[DataBufLength1-1])/prime;
        if (min<3)
        {
            return false;
        }
        for (;min<=max;min++)
        {
            this->m_pDataBuf[(prime*min-base)>>1]=0;
        }
        return true;
    }
};

void main()
{

    myLong nBegin = GetTickCount();
    //建立素数表
    InitBasePrime();
    //处理从M到G的数
    GenF1MTo4G * p1 = new GenF1MTo4G;
    p1->GenPrimProcess();
    delete p1;
    //处理从G到G的数
    GenF4GTO10G *p2 = new GenF4GTO10G;
    p2->GenPrimeProcess();
    delete p2;
    cout<<"Time used:"<<(GetTickCount()-nBegin)/1000<<"s"<<endl;

};
原创粉丝点击