C++ 如何根据元素的某些属性删除std::vector的元素?

C++ 如何根据元素的某些属性删除std::vector的元素?,c++,algorithm,stl,vector,C++,Algorithm,Stl,Vector,例如,如果您有一个std::vector,其中MyClass有一个公共方法:bool isTiredOfLife(),如何删除返回true的元素?如果 v.erase(remove_if(v.begin(), v.end(), mem_fun_ref(&MyClass::isTiredOfLife)), v.end()); 返回指向序列中最后一个元素之后的迭代器erase删除从第一个参数到最后一个参数(两个迭代器)的所有内容 使用r

例如,如果您有一个
std::vector
,其中
MyClass
有一个公共方法:
bool isTiredOfLife()
,如何删除返回true的元素?

如果

v.erase(remove_if(v.begin(), v.end(), 
                 mem_fun_ref(&MyClass::isTiredOfLife)), 
        v.end());
返回指向序列中最后一个元素之后的迭代器
erase
删除从第一个参数到最后一个参数(两个迭代器)的所有内容

使用remove_if是执行此操作的“正确”方法。注意不要使用迭代器循环遍历和擦除,因为删除项会使迭代器无效。事实上,任何使用erase()作为主要方法的示例在向量上都是一个坏主意,因为erase是O(n),这将使算法成为O(n^2)。这应该是一个O(n)算法

下面我给出的方法可能比remove_if快,但与remove_if不同,它不会保持元素的相对顺序。如果您关心维护顺序(即向量已排序),请使用remove_If,如上面的答案所示。如果您不关心顺序,并且要删除的项目数通常少于向量的四分之一,则此方法可能会更快:

for( size_t i = 0; i < vec.size(); )
   if( vec[i].isTiredOfLife() )
   {
      vec[i] = vec.back();
      vec.pop_back();
   }
   else
      ++i;
(大小i=0;i if(vec[i].isTiredOfLife()) { 向量[i]=vec.back(); vec.pop_back(); } 其他的 ++一,;
我忘记了remove\u if()+1。好吧,我们真的不需要擦除;我们使用remove变体是因为remove变体不会删除元素,只是将它们附加到末尾。我忘了。在我链接的页面上,它甚至是粗体的o我已经删除了我的帖子,所以没有人使用它。这不会重新排列向量中的元素吗?例如,假设输入向量已排序,输出向量不会排序,最后一个元素将占据第一个删除元素的位置。您可能希望更新答案,使其不再引用Bernard的。是的,这将重新排列向量中的元素。如果您不关心顺序(可能比remove_if快,尤其是在数据类型复杂的情况下),这是好的,但是如果您需要相对顺序保持不变,这是坏的。