筛选Eratosthenes删除列表元素

时间:2014-04-02 02:36:16

标签: c++ vector erase sieve-of-eratosthenes

我一直在研究Stroustrup的这本书: http://www.amazon.com/Programming-Principles-Practice-Using-C/dp/0321543726 我目前正在进行第4章的练习13,它要求您实施Sieve Eratosthenes算法用于查找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 max\n"
            "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
}

非常感谢任何帮助! THX!

3 个答案:

答案 0 :(得分:2)

要从STL容器中删除元素,您需要使用erase-remove惯用法: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 :(得分:1)

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

要打印出值,您需要扫描数组并仅打印出仍为1的元素的索引。

答案 2 :(得分:0)

在您的代码中,因为您要删除2,3,5,7的倍数.... 每次你的矢量大小都会改变。我建议您定义一个新变量int len = primer.size();//In this case it will be equal to Max-2之后,您可以erase()运行以更新向量。
    #包括     #包括     #包括     使用namespace std;

/*
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 max\n"
        "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

}