如何利用埃拉托色尼筛法减少空间以生成10^16以内的质数

How to reduce space to generate primes upto 10^16 using in Sieve of Eratosthenes?

本文关键字:埃拉托 筛法 空间 何利用      更新时间:2023-10-16

我已经在c++中实现了eatosthenes的Sieve,但是当输入大于10^10时代码会崩溃。编译器显示信号11(SIGSEV)。这是因为全局数组bool a[5000000000000000]; .为了检查奇数到10^16,我将数组大小设为(10^16)/2 = 5 * 10^15。如何减少空间?这个问题有一个答案如何在埃拉托色尼筛子中降低空间复杂度来生成a和b之间的素数?我尝试了,但是我的程序崩溃了。谁能提供实现细节来修复它?

#include <bits/stdc++.h>
using namespace std;
long long unsigned n,sqN;
bool a[5000000000000000];
long long int sieve_of_Eratosthenes();
int main()
{
    cout<<"Enter upper bound to generate prime upto:"<<endl;
    cin>>n;
    long long int count = sieve_of_Eratosthenes();
    cout<<"Total = "<<count<<endl;
    return 0;
}
long long int  sieve_of_Eratosthenes()
{
    long long unsigned i,j,count = 0;
    sqN = (long long unsigned) sqrt(n);
    for(i=3; i<=sqN; i+=2)
    {
        if(a[i/2]==true)
        {
            continue;
        }
        for(j = i*i; j<=n; j+=(2*i))
        {
            a[j/2] = true;
        }
    }
    if(n>=2)
    {
        count++;
        cout<<2<<endl;
    }
    for(i=3; i<=n; i+=2)
    {
        if(a[i/2]==false)
        {
            cout<<i<<endl;
            count++;
        }
    }
    return count;
}

除了超级计算机之外,你不能在任何计算机上分配这么多的内存空间。如果你只想在给定的范围内生成质数{比如说,(a,b),其中a <= b <= 10^16},你可以简单地使用Erathosthenes的Sieve来存储质数到sqrt(10^16),然后应用分段筛

使用分段筛的好处是:

  • 降低时间复杂度
  • 不需要浪费宝贵的内存。你可以很容易地用更少的空间为小范围生成质数

即使每个奇数使用一个比特,也需要6.25e14 = 625 tb来存储它。你可以将一些大的磁盘阵列映射到内存,或者使用超级计算机的RAM……但除非你有这样的硬件,我认为你不能使用埃拉托色尼的常规筛子来计算这么大的数字。