简体   繁体   English

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

[英]Trouble with the Sieve of Eratosthenes in C++

I'm trying to implement the Sieve of Erasthones in C++, and I've run into lots of problems. 我正在尝试用C ++实现Erasthones的Sieve,我遇到了很多问题。 My code is as follows: 我的代码如下:

#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;
    }
}

I don't know what the next step is. 我不知道下一步是什么。 I've looked online but I don't understand a lot of the code. 我看过网上但我不了解很多代码。 Can you please provide an example of working c++ code and how it works? 能否请您提供一个工作c ++代码及其工作原理的示例?

There's no major flaw in your code - it works, but it's a bit bulky. 您的代码中没有重大缺陷 - 它可以工作,但它有点笨重。

The basic logic is: 基本逻辑是:

  1. Fill a vector, named sieve , with 1s (chars to save memory) 用1s填充一个名为sieve的向量(用于节省内存的字符)
  2. For each prime element in the first vector, mark all of its multiples as prime 对于第一个向量中的每个素数元素,将其所有倍数标记为素数
  3. Add every prime element int he first vector the the retVector , and return the vector of all primes up until limit 将每个素数元素添加到第一个向量中的retVector ,并将所有素数的向量返回到limit

Another working implementation of the sieve in c++ might look something like the following: 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;
}

There's nothing really wrong with your code - it actually works. 有没有什么你的代码错误-它确实可以工作。 It's not the best implementation, but it's a good start if you have little to no experience coding, so congratulations! 这不是最好的实现,但如果您几乎没有经验编码,这是一个良好的开端,所以恭喜!

To see that your code works, simply add another loop that prints the prime numbers: 要查看您的代码是否有效,只需添加另一个打印素数的循环:

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 << " ";
}

What your code does: 你的代码做了什么:

  • It initializes an array arr of size max which, at the end of the execution of your algorithm, will have arr[i] == true if i is a prime number and arr[i] == false otherwise; 它初始化一个数组arr大小的max ,其在你的算法的执行结束时,将有arr[i] == true如果i是一个素数, arr[i] == false否则;

  • Your algorithm works by first assuming that each number is prime. 您的算法首先假设每个数字都是素数。 Then, it starts correcting this assumption by setting the multiples of each number 2, 3, 4, 5, 6, ... as not being prime numbers: this is correct, because any multiple of any number other than 1 cannot be prime (as it will be divisible by that number). 然后,它开始通过将每个数字2, 3, 4, 5, 6, ...的倍数设置为不是素数来纠正这个假设:这是正确的,因为除1之外的任何数字的任何倍数都不能是素数(因为它可以被这个数字整除)。

Your code and algorithm can be improved in a variety of ways: 您的代码和算法可以通过多种方式进行改进:

  • Only mark multiples of prime numbers as not being prime, because the other will have already been marked previously. 仅将素数的倍数标记为不是素数,因为另一个素数已经被标记过了。 This will make your program more efficient; 这将使您的计划更有效率;

  • Improve the memory usage by using a bitset ; 使用bitset改善内存使用量;

  • Start marking off multiples from the squares of primes; 从素数的平方开始标记倍数;

  • Treat 2 as an edge case, since it is the only even prime. 2视为边缘情形,因为它是唯一的素数。 Then you can start iterating numbers starting from 3 and going in increments of 2 : 3, 5, 7, 9, ... . 然后你可以开始迭代从3开始的数字,并以23, 5, 7, 9, ...增量进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM