C++ vector正确删除元素Erase–remove用法

47 篇文章 2 订阅
14 篇文章 0 订阅

来源:维基百科

动机

一个常见的编程任务是从集合collection中删除等于某个值或满足某个标准的所有元素。C++语言可以通过手写循环完成这个任务。但更好的办法是使用C++标准模板库中的算法来实现。

erase用于从一个集合中删除一个元素,但是对于基于数组的容器,如vector存储在被删除元素后的所有元素都需要向前移动以避免集合中有一个空位(gap),在同一容器中多次调用产生了大量移动元素的开销。

algorithm库提供了removeremove_if算法。由于这些算法运行在两个前向迭代器确定的元素范围上,它们没有底层容器或集合的具体知识。这些算法并不从容器删除元素,而是把不符合删除标准的元素搬移到容器的前部,并保持这些元素的相对次序。 该算法一次通过数据范围即可实现该目标。

由于没有元素被删除,因此容器尺寸保持不变。容器尾部的元素都是需要被删除的,但其状态未指定unspecified stateremove返回一个迭代器指向尾部这些需要用erase删除的元素的第一个。

同样的事情(删除多个元素),用容器的方法erase会导致多次遍历这个容器,每一次遍历时,在被删除元素之后的所有元素都必须向前移动,其时间消耗远大于单次通过。

局限

erase–remove惯用法不能用于返回const_iterator (例如:set)的容器。

std::removestd::remove_if不能保持被删除的元素(不像std::partition, std::stable_partition)。因此,erase–remove只能用于容器的元素是全值语义不会招致资源泄露。

例子

// Use g++ -std=c++11 or clang++ -std=c++11 to compile.

#include <algorithm>  // remove and remove_if
#include <iostream>
#include <vector>  // the general-purpose vector container

bool IsOdd(int i) { return i & 1; }

void Print(const std::vector<int>& vec) {
  for (const auto& i : vec) {
    std::cout << i << ' ';
  }
  std::cout << std::endl;
}

int main() {
  // Initializes a vector that holds numbers from 0-9.
  std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  Print(v);

  // Removes all elements with the value 5.
  v.erase(std::remove(v.begin(), v.end(), 5), v.end());
  Print(v);

  // Removes all odd numbers.
  v.erase(std::remove_if(v.begin(), v.end(), IsOdd), v.end());
  Print(v);
}

/*
Output:
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 6 7 8 9
0 2 4 6 8
*/
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值