c++ - remove-erase 和 find-erase 有什么区别

标签 c++ stl

假设您要按值从 vector 中删除单个元素。 remove 之间有什么区别? -删除:

vector<int> v;
// add some values
vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it);

然后查找-删除

vector<int> v;
// add some values
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if(it != v.end())
{
  v.erase(it);
}

最佳答案

您的移除-删除代码不正确。 remove-erase 习语看起来像这样:

vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it, v.end());

在这种情况下,它具有删除所有等于 5 的值的效果,但它最大限度地减少了实现该操作所需的复制量。

您的查找-删除代码仅删除第一个等于 5 的值,因此它会执行您想要的操作。

您的移除-删除代码将所有不等于 5 的值移动到 vector 的前面(这就是 std::remove 所做的),删除 vector 的剩余元素之一,并且在此之后留下任何剩余的元素具有未指定的值(这也是 remove 所做的)。如果 vector 不包含开头的 5,它具有未定义的行为,因为在这种情况下 remove 将返回 v.end() .

因此,如果您只想删除等于 5 的几个元素,那么 std::remove 对您没有用,因为它不保留(其他)5。如果您想将非 5 值移动到开头,将 5 值移动到结尾,在删除第一个 5 之前,实际上您可以使用 std::partition 来做到这一点使用 std::remove:

auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.erase(it);

虽然,由于一个 5 和另一个一样好,你通过删除最后一个 5 而不是第一个得到相同的结果,并且当有多个 5 时它更有效:

auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.pop_back();

如果您能以某种方式确定 vector 最初包含恰好 一个等于 5 的元素(不多也不少),那么您的两段代码会做同样的事情。在这种情况下,您不需要在查找-删除代码中对 it != v.end() 进行测试,您会知道它不相等。你可以只做 v.erase(find(v.begin(), v.end(), 5))

关于c++ - remove-erase 和 find-erase 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20000013/

相关文章:

c++ - std::terminate 和空容器的析构函数

c++ - 在 UWP C++ 应用程序中获取 CreateFile() 设备路径的首选方法是什么?

c++ - C++ multiset lower_bound 的意外输出

c++ - vector 问题 (std::out_of_range)

c++ - 不使用指针遍历 C 风格的数组

c++ - 更大的仿函数不起作用

c++ - 有没有办法将 'std::vector 2d' 作为指向 '2d c array' 的指针传递给函数

c++ - 二叉搜索树中的节点拒绝删除

c++ - 具有 2 个无值参数的函数

c++ - 多态性 : "A pointer to a bound function may only be used to call the function"