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

C++ 如何检查擦除删除操作是否成功?,c++,erase-remove-idiom,C++,Erase Remove Idiom,这是我第一次使用这个习惯用法,我有一个向量v1,其中的元素必须是另一个向量v2中元素的子集。现在,想象一下v1和v2作为集合,我想执行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

这是我第一次使用这个习惯用法,我有一个向量
v1
,其中的元素必须是另一个向量
v2
中元素的子集。现在,想象一下
v1
v2
作为集合,我想执行
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!");
}
std::vector v1;
std::向量v2;
//以某种方式填充v1、v2

对于(size_t i=0;i只需检查是否删除了任何元素:

const auto orig_size = v2.size();
v2.erase(std::remove(v2.begin(), v2.end(), v1[i]), v2.end());
if (v2.size() == orig_size)
或者将其拆分(没有任何内容强迫您在单个语句中执行删除和擦除操作):


如果对两个向量进行排序并使用算法一起遍历它们,则可以使代码更加高效。当前代码为O(n²)因为它在整个
v2
中搜索
v1

中的每个元素,所以使用std::includes,如果向量是可以排序的。@manni66我指定它们不排序,因为它们不能排序(必须保留顺序)如果有一百万个项目,那么将两个向量按值传递给函数std::sort这些临时向量,并调用类似于
std::mismatch
的函数可能会更有效。您的代码将在未排序的数据上循环10^12次迭代,而对一百万个项目的两个临时副本进行排序所需的时间要少得多。@PaulMcKenzie谢谢你的回答。事实并非如此,我们在
v1
中讨论了数千个元素。对于代码的这一特定部分(效率不是重点)我更喜欢保持一个简单明了的代码。我认为,仅仅因为我们使用C++并不意味着我们必须总是使用最有效的解决方案,你不同意吗?)关于<代码> BoL是不一样的(向量V1,向量V2);在该函数中,
sort
并调用
std::equal
std::mismatch
?看看你的代码,需要看两三遍才能弄清楚它在做什么(它不是自我记录)。Scott Parent在他的许多优秀视频中讨论了这一点,其中为
循环编写手工编码的
,不如使用各种算法函数来完成这项工作。
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());