How to check if an erase-remove operation has been successful?

3.5k Views Asked by At

This is the first time I use this idiom and I have a vector v1 which elements must be a subset of the elements in another vector v2. Now, imagining v1 and v2 as sets, I want to perform v2-v1 and throw an exception if v1[i] doesn't exists in v2 (for any meaningful i).

I came up with this:

std::vector<T> v1;
std::vector<T> v2;
//fill v1, v2 somehow
for(size_t i=0; i<v1.size(); i++){
  v2.erase(std::remove(v2.begin(), v2.end(), v1[i]), v2.end());
  if(/*erase option failed because v1[i] doesn't exists in v2*/)
    throw std::runtime_exception (std::to_string(i)+"-th in v1 doesn't exists in v2!");
}

How can I fill the if condition?

1

There are 1 best solutions below

0
On

Simply check if any elements were removed:

const auto orig_size = v2.size();
v2.erase(std::remove(v2.begin(), v2.end(), v1[i]), v2.end());
if (v2.size() == orig_size)

Or split it up (nothing forces you to do the remove and erase in a single statement):

const auto last = std::remove(v2.begin(), v2.end(), v1[i])
if (last == v2.end())
  throw std::runtime_exception (std::to_string(i)+"-th in v1 doesn't exists in v2!");
v2.erase(last, v2.end());

You could make the code far more efficient if you keep both vectors sorted and use an algorithm to walk through them together. Your current code is O(n²) because it searches the whole of v2 for every element in v1.