Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erasing elements from a vector, if they are also in another vector

Tags:

c++

vector

erase

Suppose I've a vector a = {"the", "of"} and a vector b = {"oranges", "the", "of", "apples"}.

I want to compare both vectors and remove the elements from a which are also in b. This is what I came up with:

for (int i = 0; i < a.size(); i++) {
    for (int j =0; j < b.size(); j++) {
       if (a[i] == b[j]) {
          a.erase(a.begin() + i);
       }
    }
}

But this loop is not removing the last element in a. Weird!

like image 661
muqsitnawaz Avatar asked Nov 30 '14 20:11

muqsitnawaz


1 Answers

The problem is that when you remove the first element of a the index gets incremented from 0 to 1. On the next iteration of the loop the size of the vector is 1 which meets the condition of the outer loop causing it to terminate. You can avoid any trickery that may be necessary to fix this by simply using std::remove_if, std::find, and a lambda.

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

int main()
{
    std::vector<std::string> a{ "the", "of" };
    std::vector<std::string> b{ "oranges", "the", "of", "apples" };

    auto pred = [&b](const std::string& key) ->bool
    {
        return std::find(b.begin(), b.end(), key) != b.end();
    };

    a.erase(std::remove_if(a.begin(), a.end(), pred), a.end());

    std::cout << a.size() << "\n";
}

A better test would be to switch the contents of a and b. This will remove "the" and "of" leaving you with "oranges" and "apples".

like image 174
Captain Obvlious Avatar answered Sep 29 '22 18:09

Captain Obvlious