带有阵列的Eratosthenes的C ++筛子

时间:2013-08-18 17:45:22

标签: c++ arrays stl sieve-of-eratosthenes

我想用C ++编写着名的Eratosthenes Sieve,只使用数组,因为它可以删除一些元素来找出素数。 我不想使用STL(矢量,设置)......只是阵列!我怎么能意识到它?

我试着解释为什么我不想使用STL集合运算符:我从一开始就学习C ++,我认为STL当然对程序员有用,但建立在标准库上,所以我和#39; d喜欢使用以前的运算符和命令。我知道STL可以让一切变得更容易。

2 个答案:

答案 0 :(得分:2)

the sieve of Eratosthenes效率的关键在于它没有,重复 ,删除/删除/丢弃等等复合材料枚举它们,而只是标记它们。

保留所有数字可以保留我们使用数字值作为此数组中的地址的能力,从而直接解决它:array[n]。当在现代random-access memory计算机上实现时,这就是筛子的枚举和标记每个素数的倍数的效率(就像integer sorting algorithms一样)。

为了使该数组模拟一个集合,我们为每个条目赋予两个可能的值:flags onoffprimecomposite10。是的,我们实际上只需要一个,而不是字节来表示筛子阵列中的每个数字,提供我们在处理它们时不会删除它们中的任何一个。

顺便说一下,vector<bool>会自动打包,逐位代表bool。非常方便。

答案 1 :(得分:1)

来自Algorithms and Data Structures

#include<iostream>
#include<cmath>
#include<cstring>

using namespace std;

void runEratosthenesSieve(int upperBound) {

      int upperBoundSquareRoot = (int)sqrt((double)upperBound);
      bool *isComposite = new bool[upperBound + 1];
      memset(isComposite, 0, sizeof(bool) * (upperBound + 1));

      for (int m = 2; m <= upperBoundSquareRoot; m++) {  
            if (!isComposite[m]) {
                  cout << m << " ";
                  for (int k = m * m; k <= upperBound; k += m)
                        isComposite[k] = true;
            }
      }
      for (int m = upperBoundSquareRoot; m <= upperBound; m++)
            if (!isComposite[m])
                  cout << m << " ";

      delete [] isComposite;
}


int main()
{
 runEratosthenesSieve(1000);
}

您不想使用STL,但这不是一个好主意

STL让生活变得更加简单。

仍然使用std::map

考虑此实现
int  max = 100;
S sieve;

for(int it=2;it < max;++it)
    sieve.insert(it);

for(S::iterator it = sieve.begin();it != sieve.end();++it)
{
    int  prime   = *it;
    S::iterator x = it;
    ++x;
    while(x != sieve.end())
        if (((*x) % prime) == 0)
            sieve.erase(x++);
        else
            ++x;
}

for(S::iterator it = sieve.begin();it != sieve.end();++it)
 std::cout<<*it<<std::endl;