[英]Sieve of Eratosthenes C++
currently I'm working on a project, where I want to calculate all prime numbers. 目前,我正在一个项目中,我要在其中计算所有素数。 When I compile (MINGW Windows Comp.) the programm crashes and returns a random error number. 当我编译(MINGW Windows Comp。)时,程序崩溃并返回一个随机错误号。 This is the Code I've written: 这是我编写的代码:
http://pastebin.com/4vVnAM2v 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;
}
}
At this point: 这一点:
erg = j * i;
prim[erg] = false;
you are going to eventually access beyond the bounds of prim
, since both i
and j
can have a value of up to nmax - 1
, so erg
will have a max value of (nmax - 1) * (nmax - 1)
. 您最终将超出prim
的范围,因为i
和j
的值都可以高达nmax - 1
,因此erg
的最大值为(nmax - 1) * (nmax - 1)
。 You need to check for this condition and break if erg >= nmax
, eg 您需要检查这种情况并在erg >= 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
Another way to fix this problem is to avoid extra steps in your loop: 解决此问题的另一种方法是避免循环中的额外步骤:
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;
}
}
}
This has the effect of 1) not looping through nmax
items nested (reducing your overall complexity from O(n^2) to O(n * (n/2 + n/6 + n/10 + ...) which is effectively O(n log n), and 2) not requiring an additional bounds check since you are never going out of bounds in your looping condition. 这具有以下效果:1)不循环遍历嵌套的nmax
项(将您的总体复杂度从O(n ^ 2)降低到O(n *(n / 2 + n / 6 + n / 10 + ...)),这是有效的O(n log n)和2)不需要额外的边界检查,因为在循环条件下您永远不会超出边界。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.