素数600万以上

时间:2020-08-03 09:21:32

标签: c++ primes memset sieve-of-eratosthenes largenumber

我正在用Hackerrank解决一个问题,问题是要找到一个范围内的素数计数。由于使用常规方法会面临超时问题,因此我使用了Eratosthenes的Sieve。除了两个隐藏的测试用例之外,大多数测试用例都可以工作。我在GDB编译器中运行了该代码,发现该代码仅支持不超过600万的值。我该怎么办?代码如下:

#include<cstring>
#include<cstdio>
#include <iostream>
#include <algorithm>
using namespace std;


void SieveOfEratosthenes(unsigned long long int a,unsigned long long int b) 
{ 
    unsigned long long int count=0; 
    bool prime[b+1]; 
    memset(prime, true, sizeof(prime)); 
  
    for (unsigned long long int p=2; p*p<=b; p++) 
    { 
        // If prime[p] is not changed, then it is a prime 
        if (prime[p] == true) 
        { 
            for (unsigned long long int i=p*p; i<=b; i += p) 
                prime[i] = false; 
        } 
    } 
  
    for (unsigned long long int p=a; p<b; p++) 
       if (prime[p] &&p!=1) 
           count++;
    cout<<count;
          
} 
  
int main() 
{ 
    unsigned long long int a,b;
    cin>>a>>b;
    SieveOfEratosthenes(a,b); 
    return 0; 
} 

2 个答案:

答案 0 :(得分:3)

看起来像经典堆栈溢出。 bool prime[b+1];被分配在堆栈上,您已经达到了极限。

如果该程序在Linux上运行,则允许的最大堆栈大小通常总计约为8MB或更小,因此很有可能您刚刚超过了该大小。

将其移出堆栈,或者执行位打包而不是完整的bool,它应该又可以正常工作了。

答案 1 :(得分:3)

您正在函数中创建一个布尔数组,该数组将存储在堆栈中。在Windows上,堆栈的典型最大大小为1MB,而在典型的现代Linux上,堆栈的最大大小为8MB。您正在创建一个包含600万条记录的数组,这将接近6MB。

要解决此问题,您可以创建一个vector而不是数组,该数组将成为堆中的stored