运行时错误(SIGSEGV)SPOJ筛选Eratosthenes

时间:2013-05-27 20:58:44

标签: c++ algorithm math sieve-of-eratosthenes

嗨我这个问题收到SIGSEGV错误,不知道问题出在哪里:http://www.spoj.com/problems/PRIME1/ 我试图通过维基百科上给出的Eratosthenes算法来解决它。 这是我的代码,请提前帮助谢谢。

int main()
{
   int t;   // test cases

   cin>>t;

   while(t--)
   {
      long int m,n;
      cin>>m>>n;


      if( 1 <= m <= n <= 1000000000 && n-m<=100000)
      {
         bool a[n];
         for(long int i=2;i<=n;i++)
         {
            a[i]=true;  // set all to true
         }
         a[0]=false;
         a[1]=false;
         for( long int i=2;i*i<=n;i++)
         {
            if(a[i])
            {
               for( long int k=i*i;k<=n;k+=i)
               {
                  a[k]=false;
               }
            }
         }
         for(long int i=m;i<=n;i++)
         {
            if(a[i])
               cout<<i<<endl;         //Now all i such that a[i] is true are prime.
         }
         cout<<endl;
      }
      else
         return -1;
   }

   return 0;
}

3 个答案:

答案 0 :(得分:4)

您必须使用gdb才能确切了解发生的情况。这段代码有很多问题。

  1. 正如评论中所指出的,对于n足够大,a[n]会溢出堆栈。

  2. 您的第一个和第三个for循环中出现了一个错误的错误;您检查a[n]但最多只分配到a[n-1]。所有i <= n都应为i < n

  3. if( 1 <= m <= n <= 1000000000 && n-m<=100000)可能不是你想要的;对于任何正整数'n',(1 <= m <=n)将为真

答案 1 :(得分:2)

There are 3401 primes below the square root of 109。这就是你需要筛选低于10 9 上限的任何数字段。

首先,筛选从2到31622的一个段。将得到的3401个素数整数存储在一个数组中。

然后,对于每对数字m <= n, m >= n - 100000,创建一个临时数组,覆盖从mn的段,并使用您在第一步中计算的素数对其进行筛选。当素数的平方高于给定n时,您可以停止每次筛选:

for( i=0; primes[i]*primes[i] <= n; ++i)
{
    ....

另见my posts about the "offset sieve" of Eratosthenes

答案 2 :(得分:0)

此问题已在SO上处理过。例如,请参阅Sieve of Eratosthenes on Stack Overflow。您可能还想阅读描述典型C实现的博客:C implementation of Sieve of Eratosthenes。如上所述,您的代码存在多个问题,实际上您需要考虑完全重新组织它们。请阅读链接的帖子,以获得有关如何成功完成此操作的建议。