找到值并从向量中删除

时间:2014-04-15 21:42:39

标签: c++ vector

你好假设有5个元素的向量

vector<int> V;
for (int i=0;i<5;i++){
v.push_back(i);
}

现在我如何使用find if和erase来擦除向量中大于2的值? 请你建议我准备的示例代码......但我不确定。 致谢

3 个答案:

答案 0 :(得分:5)

您可以使用erase-remove idiom std::remove_if和合适的仿函数。例如

V.erase(std::remove_if(std::begin(V), std::end(V),
                       [](int i){ return i > 2; } ), 
                       std::end(V) );

如果你坚持使用pre-C ++ 11编译器,那么<​​/ p>

bool func(int i) { return i > 2; }

V.erase(std::remove_if(V.begin(), V.end(), func), V.end());

答案 1 :(得分:1)

这是一种替代解决方案,只使用std::remove_if方法和迭代器而不使用erase

typedef std::vector<int> IntVector;
IntVector v;
// fill
for (IntVector::iterator it = v.begin(); it != v.end();) {
    if (*it > 2) {
        it = v.erase(it);
    } else {
        ++it;
    }
}

答案 2 :(得分:1)

您可以根据谓词(条件)从向量中删除:

std::vector<int>::iterator it = std::remove_if(      // it shifts, doesn't 
                                v.begin(), v.end(),  // reduces the physical size
                                [](int i){ return i > 2; } ));

并删除不需要的值:

v.erase( it, v.end()); // this is needed as remove_if doesn't erase
                       // elements that don't meet condition (are not to be
                       // removed), it simply moves those that don't meet 
                       // condition to the begin.
                       // now we reduce the physical size

为什么remove_if后面跟着擦除

  

通过移动(通过移动分配)来完成移除   范围内的元素以不使用的元素的方式   被删除出现在范围的开头。相对的顺序   保留的元素和物理大小   容器没有变化。迭代器指向之间的元素   新的逻辑结束和范围的物理结束仍然存在   可解除引用,但元素本身具有未指定的值   (根据MoveAssignable后置条件)。通常会调用删除   然后调用容器的擦除方法,擦除方法   未指定的值并将容器的物理大小减小到   匹配其新的逻辑大小。

http://en.cppreference.com/w/cpp/algorithm/remove

实施例

// Let's imagine your vector is

v = { 1, 2, 3, 4, 5};
      ^              ^
      begin          end

// copy( v.begin(), v.end(), ostream_iterator<int>(cout));
will print: 12345

after remove_if vector becomes:

v = { 1, 2, 3, 4, 5};
      ^     ^        ^
      begin it       end
// copy( v.begin(), v.end(), ostream_iterator<int>(cout)); 
// will still print a vector of size 5: 12345
// but 

// copy( v.begin(), it, ostream_iterator<int>(cout));
will print: 12

after v.erase( it, v.end()); vector becomes:
v = { 1, 2};
      ^     ^
      begin end
// copy( v.begin(), v.end(), ostream_iterator<int>(cout));
will print: 12

compiled example


C ++ 03:

bool f(int i) { return i > 2; }
std::vector<int>::iterator it = std::remove_if( v.begin(), v.end(), f); // shifts
v.erase( it, v.end());                               // reduces the physical size