Search code examples
c++vectorerasesieve-of-eratosthenes

Sieve Of Eratosthenes Deleting list elements


I have been working through the book by Stroustrup: http://www.amazon.com/Programming-Principles-Practice-Using-C/dp/0321543726 I am currently working on exercise 13 of chapter 4, which asks you to implement the Sieve of Eratosthenes algorithm to find the prime numbers between 1 and 100. http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes I am currently trying to delete the multiples of 2. I tried both the erase function and the remove_if(which causes odd segmentation errors). I am not looking for any implementation advice, just help with removing elements of vectors.

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

Any help is greatly appreciated! Thx!


Solution

  • To erase elements from STL containers, you'll need to use the erase-remove idiom: 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());
            ...
        }
    

    To remove any value (just not multiples of 2), you can use function objects, or functors.

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

    And to use it:

        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());