就地std :: copy_if

Man*_*uel 4 c++ stl c++11

在我看来,这std::copy_if对过滤容器非常有用:

std::vector<int> vec { 1, 2, 3, 4 };
auto itEnd = std::copy_if(vec.begin(), vec.end(), vec.begin(),
                          [](int i) { return i > 2; });
vec.resize(itEnd - vec.begin());
Run Code Online (Sandbox Code Playgroud)

但是,std::copy_if指定输入和输出范围可能不重叠.

还有其他选择吗?

leg*_*s2k 20

copy_if 主要用于将范围复制到另一个范围/容器即设计,算法的性质是将满足某些条件的元素复制到另一个(非重叠)范围或新容器.

remove_if更适合您的需求; 它完全按照您的期望过滤掉.但是,它只通过覆盖删除元素; 函数完成后,旧端和新端之间的残余将是未指定的元素,需要使用手动擦除erase,如下所示:

std::vector<int> vec { 1, 2, 3, 4 };
vec.erase(std::remove_if(std::begin(vec),
                         std::end(vec),
                         [](int i) { return i <= 2; }),
          std::end(vec));
Run Code Online (Sandbox Code Playgroud)

这是一个名为erase-remove的C++习语.


而不是copy_if,如果copy你想要的话,那么你就可以选择重叠范围,即copy_backward; 来自文档

如果d_first在[first,last]内,则必须使用std :: copy_backward而不是std :: copy.

  • 您的最后一段不正确:每次删除后都不会有所有元素的移位(这会导致O(n ^ 2)性能).性能将是线性的,类似于`copy_if`. (3认同)
  • @Angew:你自己提供了参考.该标准将复杂性与谓词的应用程序数量联系起来.因此,除非复制和移动的成本恰好为零,否则显然复制/移动操作的数量与该数量成正比或更小.它不能比线性更复杂,否则就是定义复杂性的方式. (3认同)
  • @ legends2k您链接的可能实现是线性时间,并且不按照您的说法操作. (2认同)