埃拉托色尼筛 删除列表元素

Sieve Of Eratosthenes Deleting list elements

本文关键字:删除 列表元素 埃拉托      更新时间:2023-10-16

我一直在研究Stroustrup的书:http://www.amazon.com/Programming-Principles-Practice-Using-C/dp/0321543726我目前正在进行第 4 章的第 13 个练习,它要求您实现筛子埃拉托色尼算法,以找到 1 到 100 之间的质数。http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes我目前正在尝试删除 2 的倍数。我尝试了擦除功能和remove_if(这会导致奇怪的分割错误)。我不是在寻求任何实现建议,只是帮助删除矢量元素。

 #include "std_lib_facilities.h"
#include <math.h>
#include <vector>
/*
This program attempts to find the prime numbers in the range of a value
using the Sieve of Eratosthenes algorithm.
*/
int main() {
    vector<int>primer;
    cout<<"This program calculates prime numbers up until a value maxn"
            "and prints these out."<<endl;
    int max = 100;
    for (int i = 2; i <= max; i += 1) { //creates a list of integers from 2 to 100.
        primer.push_back(i);
    }
    for (int n = 2; n < max; n += 2) { //attempts to delete the multiplies of 2, excluding 2 itself.
       primer.erase(?);
    }
     copy(primer.begin(), primer.end(), ostream_iterator<int>(cout, " "));//prints the elements of the vector
}

任何帮助都非常感谢! 谢谢!

要从 STL 容器中删除元素,您需要使用擦除-删除习惯用法:http://en.wikipedia.org/wiki/Erase-remove_idiom

    bool is_even(int n) { return 0 == n % 2; }
    int main() 
    {
        ...
        v.erase(std::remove_if(v.begin(), v.end(), is_even), v.end());
        ...
    }

要删除任何值(不是 2 的倍数),可以使用函数对象或函子。

    class is_multiple_of
    {
        int m_div;
    public:
        is_multiple_of(int div) : m_div(div) {}
        bool operator()(int n) { return 0 == n % m_div; }
    };

并使用它:

    v.erase(std::remove_if(v.begin(), v.end(), is_multiple_of(3)), v.end());
    v.erase(std::remove_if(v.begin(), v.end(), is_multiple_of(5)), v.end());

出于效率原因,您通常不会删除埃拉托色尼筛子中的元素,而只需将它们标记为未使用即可。您实际上不必将数字 1 到 100(或 1000 或其他)存储在向量中。相反,将向量的每个成员设置为 1(或 0),然后将其设置为相反,以指示它已被划掉。元素的数值只是它在数组中的位置。要划掉每n个数字,您必须扫描数组,一遍又一遍地数到n,标记掉这些数字。

要打印出值,请扫描数组,只打印出仍为 1 的元素的索引。

在您的代码中,由于您要删除 2,3,5,7 的倍数....每次矢量大小都会发生变化。我建议您定义一个新变量int len = primer.size();//In this case it will be equal to Max-2之后,您可以erase()函数来更新向量。
#include #include #include 使用命名空间标准;

/*
This program attempts to find the prime numbers in the range of a value
using the Sieve of Eratosthenes algorithm.
*/
int main() {
    vector<int>primer;
    cout<<"This program calculates prime numbers up until a value maxn"
        "and prints these out."<<"n";
    int max = 100;
    for (int i = 2; i <= max; i += 1) { //creates a list of integers from 2  to 100.
        primer.push_back(i);
    }
    int len = primer.size();
    for (int i = 2; i < len; ) { //attempts to delete the multiplies of 2, excluding 2 itself.
         if(primer[i]%2==0) {
             primer.erase(primer.begin()+n);
             len = primer.size();
         }
         else
            i++;
}
 copy(primer.begin(), primer.end(), ostream_iterator<int>(cout, " "));//prints the elements of the vector

}