Eratosthenes的Sieve,数组太大,以至于内存超出界限

时间:2015-12-29 12:32:19

标签: c++ arrays algorithm

我想得到2和pow(2,32)之间的所有素数,但是,因为pow(2,32)很大,我不能声明那个大数组。以下是我的代码

struct prims_n
{
    long long *prim;
    long long  size;
};

struct prims_n get_prim_number(long long number)
{
    long long count = 0;
    struct prims_n result;
    bool* a = new bool[number+1];
    memset(a, 1, number+1);
    for(long long i = 2; i <= sqrt(number); i ++)
    {
        if(a[i])
        {
            for(long long j = 2; j <= number/i; j ++)
            {
                a[i*j] = 0;
            }
        }
    }
    for (long long i = 2; i <= number; i++)
    {
        if (a[i]) count ++;
    }
    result.size = count;
    long long k = 0;
    result.prim = new long long[count];
    for (long long i = 2; i <= number; i++)
    {

        if (a[i] && k < count)
        {
            result.prim[k] = i;
            k ++;
        }
    }
    return result;
}

int main(int argc, char* argv[])
{

    struct  prims_n result = get_prim_number(pow(2, 26));
    cout << "prim numbers:" << result.size 
        << " pow(2, 32)=" <<  pow(2, 32) << endl;
    return 0;
}

我的操作系统为Windows,IDE为Visual Studio 2012 数字pow(2,32)太大而Sieve of Eratosthenes的计算效率不高。那么,我该怎么办?

2 个答案:

答案 0 :(得分:4)

简单方法:构建64位目标并安装大量RAM。

或者你可以通过不为每个数字存储一个int而只减少一点来减少所需的内存。 std::vector<bool>std::bitset<N>将是很好用的容器。 bitset要求在编译时知道大小,vector允许它更改。 BTW,vector<bool>专门用于优化内存使用。

当然你并不需要存储所有数字1..N,因为你知道偶数不能是素数。所以你可以使用一个数组,例如索引i的元素代表2*i+1是素数时的信息。

其他选项:只存储素数,然后对每个要测试的新数字进行测试,尝试将其除以已计算和存储的素数(不是全部,最多只能达到sqrt())。

或者使用窗口视图进入筛网:将已知的素数存储在一个容器中,并为完整缓冲区的一部分分配空间。如果您已完成缓冲区,请转到下一个窗口。

答案 1 :(得分:-2)

素数在表格(6K + 1)或(6K - 1)上, 循环k并检查6K + 1或6K-1是否不能被2,3,5,7整除为