【问题标题】:Sieve of Eratosthenes C++埃拉托色尼筛法 C++
【发布时间】:2013-10-03 18:27:44
【问题描述】:

目前我正在做一个项目,我想计算所有素数。 当我编译(MINGW Windows Comp.)时,程序崩溃并返回一个随机错误号。 这是我写的代码:

http://pastebin.com/4vVnAM2v

/*
    Sieb des Eratosthenes
*/

#include <iostream>
#include <math.h>
using namespace std;

main()
{
    //variablendeklaration
    unsigned int nmax=100;
    unsigned int i,j,erg;
    bool prim[nmax];

    //Initialisieren
    prim[0]=false;
    prim[1]=false;

    //array prim[i] erstellen
    for(i=2;i<nmax;i++)
    {
        prim[i]=true;
    }




    for(i=2;i<nmax;i++) //alle Primzahlen durchlaufen
    {
        if(prim[i] == true) //auf Prim prüfen
        {
            for(j=2;j<nmax;j++) //multiplizieren und wegstreichen
            {
                erg = j * i;
                prim[erg] = false;
            }
        }
    }

    for(i=2;i<nmax;i++)
    {
        cout << prim[i] << endl;
    }


}

【问题讨论】:

  • 除非你被禁止 - 使用矢量代替 - vector&lt;bool&gt; primes;
  • 当您开始使用相当大的数字(例如 > 100 万)时,这个 O(n^2) 版本的筛子将永远耗时。

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


【解决方案1】:

此时:

            erg = j * i;
            prim[erg] = false;

您最终将访问超出prim 的范围,因为ij 的值都可以达到nmax - 1,因此erg 的最大值将为(nmax - 1) * (nmax - 1) .您需要检查这种情况并在erg &gt;= nmax 时中断,例如

            erg = j * i;
            if (erg < nmax)          // if i * j still within bounds
                prim[erg] = false;   // set prim[i * j] to false
            else                     // else i * j now >= nmax
                break;               // break out of loop and try next i value

【讨论】:

  • 这是什么意思?我必须在 for 循环中更改 var "nmax" 吗?
【解决方案2】:

解决此问题的另一种方法是避免循环中的额外步骤:

for(i=2; i < nmax; i++)
{
    if(prim[i] == true)
    {
        for (j = 2 * i; j < nmax; j += i) // state j at 2i, increment by i
        {
            prim[j] = false;
        }
    }
}

这具有 1) 不循环遍历嵌套的 nmax 项目的效果(将您的整体复杂性从 O(n^2) 降低到 O(n * (n/2 + n/6 + n/10 + .. .) 这实际上是 O(n log n),并且 2) 不需要额外的边界检查,因为您在循环条件下永远不会超出边界。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多