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

时间:2009-03-14 07:42:47

标签: c++ algorithm stl vector

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

2 个答案:

答案 0 :(得分:21)

我更喜欢remove_if

v.erase(remove_if(v.begin(), v.end(), 
                 mem_fun_ref(&MyClass::isTiredOfLife)), 
        v.end());

remove_if返回一个迭代器,指向仍在序列中的最后一个元素。 erase擦除从第一个参数到最后一个参数(两个迭代器)的所有内容。

答案 1 :(得分:6)

使用remove_if是执行此操作的“正确”方法。注意不要使用迭代器来循环和擦除,因为删除项会使迭代器无效。事实上,任何使用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;