如何检查擦除 - 删除操作是否成功?

jus*_*rld -1 c++ erase-remove-idiom

这是我第一次使用这个成语,我有一个向量v1,其中元素必须是另一个向量中元素的子集v2.现在,想象v1v2作为集合,我想执行v2-v1并抛出异常(如果v1[i]不存在)v2(对于任何有意义的i).

我想出了这个:

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!");
}
Run Code Online (Sandbox Code Playgroud)

我该如何填写这个if条件?

Jon*_*ely 7

只需检查是否删除了任何元素:

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

或者拆分(没有任何东西强迫你在一个语句中删除和删除):

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());
Run Code Online (Sandbox Code Playgroud)

如果你保持两个向量排序并使用算法一起遍历它们,你可以使代码更有效.您当前的代码是O(n²),因为它会搜索整个v2元素v1.