Eratosthenes算法的筛选

Rao*_*ouL 6 c++ algorithm

我目前正在阅读"编程:使用C++的原理和实践",在第4章中有一个练习,其中:

我需要使用Sieve of Eratosthenes算法制作一个程序来计算1到100之间的素数.

这是我提出的计划:

#include <vector>
#include <iostream>

using namespace std;

//finds prime numbers using Sieve of Eratosthenes algorithm
vector<int> calc_primes(const int max);

int main()
{
    const int max = 100;

    vector<int> primes = calc_primes(max);

    for(int i = 0; i < primes.size(); i++)
    {
        if(primes[i] != 0)
            cout<<primes[i]<<endl;
    }

    return 0;
}

vector<int> calc_primes(const int max)
{
    vector<int> primes;

    for(int i = 2; i < max; i++)
    {
        primes.push_back(i);
    }

    for(int i = 0; i < primes.size(); i++)
    {
        if(!(primes[i] % 2) && primes[i] != 2)
             primes[i] = 0;
        else if(!(primes[i] % 3) && primes[i] != 3)
             primes[i]= 0;
        else if(!(primes[i] % 5) && primes[i] != 5)
             primes[i]= 0;
        else if(!(primes[i] % 7) && primes[i] != 7)
             primes[i]= 0;
    }   

    return primes;
}
Run Code Online (Sandbox Code Playgroud)

不是最好的或最快的,但我还在本书的早期,并且对C++知之甚少.

现在问题是,直到max不大于500控制台上打印的所有值,如果max > 500不是所有内容都被打印出来.

难道我做错了什么?

PS:任何建设性的批评都会受到高度赞赏.

Mar*_*ork 5

把筛子想象成一套.
按顺序浏览设置.对于thesive中的每个值,删除所有可被它除的数字.

#include <set>
#include <algorithm>
#include <iterator>
#include <iostream>


typedef std::set<int>   Sieve;

int main()
{
    static int const max = 100;

    Sieve   sieve;

    for(int loop=2;loop < max;++loop)
    {
        sieve.insert(loop);
    }


    // A set is ordered.
    // So going from beginning to end will give all the values in order.
    for(Sieve::iterator loop = sieve.begin();loop != sieve.end();++loop)
    {
        // prime is the next item in the set
        // It has not been deleted so it must be prime.
        int             prime   = *loop;

        // deleter will iterate over all the items from
        // here to the end of the sieve and remove any
        // that are divisable be this prime.
        Sieve::iterator deleter = loop;
        ++deleter;

        while(deleter != sieve.end())
        {
            if (((*deleter) % prime) == 0)
            {
                // If it is exactly divasable then it is not a prime
                // So delete it from the sieve. Note the use of post
                // increment here. This increments deleter but returns
                // the old value to be used in the erase method.
                sieve.erase(deleter++);
            }
            else
            {
                // Otherwise just increment the deleter.
                ++deleter;
            }
        }
    }

    // This copies all the values left in the sieve to the output.
    // i.e. It prints all the primes.
    std::copy(sieve.begin(),sieve.end(),std::ostream_iterator<int>(std::cout,"\n"));

}
Run Code Online (Sandbox Code Playgroud)

  • 集合在第21章中.RaouL正在研究第4章. (2认同)

Dav*_*ley 5

我不知道为什么你没有得到所有输出,因为看起来你应该得到一切.你错过了什么输出?

筛子被错误地实施.就像是

vector<int> sieve;
vector<int> primes;

for (int i = 1; i < max + 1; ++i)
   sieve.push_back(i);   // you'll learn more efficient ways to handle this later
sieve[0]=0;
for (int i = 2; i < max + 1; ++i) {   // there are lots of brace styles, this is mine
   if (sieve[i-1] != 0) {
      primes.push_back(sieve[i-1]);
      for (int j = 2 * sieve[i-1]; j < max + 1; j += sieve[i-1]) {
          sieve[j-1] = 0;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

会实施筛子.(上面的代码写在了我的头顶;不能保证工作甚至编译.我认为它没有在第4章末​​尾没有涵盖的任何内容.)

primes像往常一样返回,打印出全部内容.