anurag86
anurag86

Reputation: 1687

vector.erase and std::remove on custom vector

I have a vector of int pairs. Assuming Itr as my iterator for this vector. I want to iterate over the vector and make a decision whether or not to remove the element from the vector. If the element of the vector is 9001,3 then i want to remove all the elements from the vector whose itr->first is 9001(irrespective or what itr->second is).

Questions:

  1. How do i remove this vector of int pairs. The following wouldn't work: vec.erase(std::remove(vec.begin(), vec.end(), Itr->first=9001), vec.end());
  2. Instead of giving a range as vec.begin() to vec.end() is it possible for me to give vec.begin as (current element being pointer by vector) - 10 and ve.end as (current element being pointed by vector)+10 ?

Example:vec.erase(std::remove(Itr-10, Itr+10, Itr->first=9001), vec.end());

It might quiet be possible that Itr+10 ot Itr-10 will result in a segmentation fault if the vector size itself is less than 10. So how to deal with this situation?

    vector<pair<int,int> > vec;

    vec.push_back(pair<int,int>(9001,1));
    vec.push_back(pair<int,int>(9001,2));
    vec.push_back(pair<int,int>(9001,3));
    vec.push_back(pair<int,int>(9001,4));
    vec.push_back(pair<int,int>(9002,1));
    vec.push_back(pair<int,int>(9002,2));
    vec.push_back(pair<int,int>(9002,3));
    vec.push_back(pair<int,int>(9002,4));
    vec.push_back(pair<int,int>(9002,5));


    vector<pair<int,int> >::iterator Itr;
    for(Itr=vec.begin();Itr!=vec.end();++Itr)
            cout<<vecItr->first<<" "<<vecItr->second;

//  vec.erase(std::remove(Itr-10, Itr+10, Itr->first=9001), vec.end()); //This doest work

    for(Itr=vec.begin();Itr!=vec.end();++Itr)
            cout<<Itr->first<<" "<<Itr->second;

Upvotes: 0

Views: 1309

Answers (1)

Revolver_Ocelot
Revolver_Ocelot

Reputation: 8785

How do i remove this vector of int pairs. The following wouldn't work:

Use lambda or custom comparator with remove_if algorithm:

vec.erase(std::remove_if(vec.begin(), vec.end(), 
                         [](auto& elem){ return elem.first == 9001;} ),
          vec.end());

Using custom comparator:

struct elem_equals
{
    typedef std::pair<int,int> elem_t
    const int value;

    elem_equals(int v) : value(v) {}

    bool operator()(elem_t& elem) 
    {
        return elem.first == value;
    }
};

//...

vec.erase(std::remove_if(vec.begin(), vec.end(), 
                         elem_equals(9001) ),
          vec.end());

Instead of giving a range as vec.begin() to vec.end() is it possible for me to give vec.begin as (current element being pointer by vector) - 10 and ve.end as (current element being pointed by vector)+10 ?

Yes. Vector iterator support pointer arithmetics, so it is easy.

It might quiet be possible that Itr+10 ot Itr-10 will result in a segmentation fault if the vector size itself is less than 10. So how to deal with this situation?

Clamp your range if there is not enough elements before or after iterator:

//iter is an iterator to vector
//vec is instance of std::vector
//replace auto with std::vector<std::pair<int,int> >::iterator for non C++11 compilers
auto begin = iter - std::min(10, iter - vec.begin());
auto end = iter + std::min(10, vec.end() - iter);

Upvotes: 3

Related Questions