在C ++中使用Eratosthenes筛选的麻烦

时间:2014-04-23 16:01:12

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

我正在尝试用C ++实现Erasthones的Sieve,我遇到了很多问题。我的代码如下:

#include <iostream>
int main()
{
    const int max = 1000;
    int count = 1;
    bool arr[max];

    for(int i = 0; i < max; ++i)
        arr[i] = true;

    for(int i = 2; i < max; i++)
    {
        //mark all multiples
        for(int j = 2; (j*i) < max-1; ++j) arr[i*j] = false;
    }
}

我不知道下一步是什么。我看过网上但我不了解很多代码。能否请您提供一个工作c ++代码及其工作原理的示例?

2 个答案:

答案 0 :(得分:2)

你的代码中没有重大缺陷 - 它有效,但它有点笨重。

基本逻辑是:

  1. 将名为sieve的向量填充为1(用于节省内存的字符)
  2. 对于第一个向量中的每个素数元素,将其所有倍数标记为素数
  3. 将第一个元素添加到retVector的第一个向量中,并返回所有素数的向量,直到limit
  4. c ++中筛选器的另一个工作实现可能如下所示:

    vector<long long> sieve(unsigned long long & limit) 
    {
        vector<char> sieve(limit, '1');
        vector<long long> retVector;
    
        for (long long i = 0; i < limit; i++)
            sieve[i] = 1;
    
        for (long long i = 2; i < limit; i++) {
            if (sieve[i] == 1) {
                for (long long j = i*i; j < limit; j += i)
                    sieve[j] = 0;
            }
        }
        for (long long i = 2; i < limit; ++i) if (sieve[i] == 1) retVector.push_back(i);
        return retVector;
    }
    

答案 1 :(得分:0)

您的代码没有真的错误 - 它确实有效。它不是最好的实现,但如果您几乎没有经验编码,这是一个良好的开端,所以恭喜!

要查看您的代码是否有效,只需添加另一个打印素数的循环:

int main()
{
    const int max = 1000;
    int count = 1;
    bool arr[max];

    for(int i = 0; i < max; ++i)
        arr[i] = true;

    for(int i = 2; i < max; i++)
    {
        //mark all multiples
        for(int j = 2; (j*i) < max-1; ++j) arr[i*j] = false;
    }

    for (int i = 2; i < max; ++i)
        if (arr[i])
            cout << i << " ";
}

您的代码的作用:

  • 它会初始化一个大小为arr的数组max,如果arr[i] == true是素数,则在算法执行结束时会有i数字和arr[i] == false否则;

  • 您的算法首先假设每个数字都是素数。然后,它开始通过将每个数字2, 3, 4, 5, 6, ...的倍数设置为不是素数来纠正这个假设:这是正确的,因为除1之外的任何数字的任何倍数都不能是素数(因为它可以被该数字整除) )。

您的代码和算法可以通过多种方式得到改进:

  • 只将素数的倍数标记为不是素数,因为另一个素数已经被标记过了。这将使您的计划更有效率;

  • 使用bitset;

  • 改善内存使用情况
  • 从素数的平方开始标记倍数;

  • 2视为边缘情况,因为它是唯一的素数。然后,您可以开始从3开始迭代数字,并以23, 5, 7, 9, ...为增量。