Search code examples
c++stlvectoriteratorerase

Loop over two vectors, remove elements of 1


I have the following toy code, intended to remove duplicates from a vector:

void overlap_removal(vector<int> &vec1, vector<int> &vec2) {
  for (vector<int>::iterator it1 = vec1.begin(); it1 != vec1.end(); ++it1) {
    for (vector<int>::iterator it2 = vec2.begin(); it2 != vec2.end(); ++it2) {
      if ((*it1)*(*it2) < 10) {
        vec1.erase();
      }
    }
  }
}

I'm doing a slightly more complicated comparison in the real code, but didn't want to confuse matters. The problem is the segmentation fault that inevitably follows the execution of this: I think this is due to the fact that I'm deleting an element and then continuing to loop over the same vector.

How can I make the code work? Is this even the right starting point? Thanks in advance


Solution

  • Try remove_if.

    The basic idea is you provide a function object such that true is returned if the passed in element should be deleted:

      class ItemInOtherVectorPred
      {
          const std::vector<int>& otherVec;
    
          ItemInOtherVectorPred(const std::vector<int>& vec) : otherVec(vec) {}
    
          // return true if removeVecsElem should be deleted
          bool operator()(const int& removeVecsElem) const
          {
              return (otherVec.find(removeVecsElem) != otherVec.end())
          }
      }
    

    Then you use an instance of that object to tell remove_if what to remove from your vector.

      void overlap_removal(vector<int> &vec1, vector<int> &vec2) 
      {
         ItemInOtherVectorPred trueIfItemInOtherVecPred( vec2);
         vector<int>::iterator eraseBeg = 
                 std::remove_if( vec1.begin(), vec1.end(), trueIfItemInOtherVecPred);
         vec1.erase(eraseBeg, vec1.end());
    
      }