删除元素

从vector或deque删除元素

  vector<int> vec = {1, 4, 1, 1, 1, 12, 18, 16}; // 删除所有的1
for (vector<int>::iterator itr = vec.begin(); itr != vec.end(); ++itr) {
if ( *itr == 1 ) {
vec.erase(itr); //你或许会想到使用erase成员函数
}
} // 的确,是可以达到目的 vec: { 4, 12, 18, 16}
// 但是复杂度是: O(n*m),每删除一个元素,后面的往前移动 // 如果使用算法remove
remove(vec.begin(), vec.end(), 1); // 复杂度 O(n)
// vec: {4, 12, 18, 16, ?, ?, ?, ?} vector<int>::iterator newEnd = remove(vec.begin(), vec.end(), 1); // 将不删除的元素移到前面,O(n)
vec.erase(newEnd, vec.end()); //删除最后无用的元素 // 算法remove_if()和unique()也是类似 // 此时vec仍然占了8个int空间: vec.capacity() == 8
vec.shrink_to_fit(); // C++ 11
// 现在vec.capacity() == 4 // For C++ 03:
vector<int>(vec).swap(vec); // 相同效果,释放空的内存

从List删除

  list<int> mylist = {1, 4, 1, 1, 1, 12, 18, 16};

  list<int>::iterator newEnd = remove(mylist.begin(), mylist.end(), 1);  // 使用算法remove,O(n)
mylist.erase(newEnd, mylist.end()); mylist.remove(1); // 成员函数更快,直接操作指针,从链上删除

从关联容器或无序容器中删除

  multiset<int> myset = {1, 4, 1, 1, 1, 12, 18, 16};

  multiset<int>::iterator newEnd = remove(myset.begin(), myset.end(), 1);  // O(n)
myset.erase(newEnd, myset.end()); myset.erase(1); // O(log(n)) or O(1)

结论

  • vector或者deque: 算法remove() + erase()
  • list:成员函数remove()
  • 关联容器或者无序容器:成员函数erase()

删除元素之后

// 看个关联容器的例子,此程序会发生什么
multiset<int> s = {1, 4, 1, 1, 1, 12, 18, 16};; multiset<int>::iterator itr;
for (itr=s.begin(); itr!=s.end(); itr++) {
if (*itr == 1) {
s.erase(itr);
cout << "Erase one item of " << *itr << endl;
}
} // 删除第一个元素成功,后面未定义的行为

解决方法:

multiset<int>::iterator itr;
for (itr=s.begin(); itr!=s.end(); ) {
if (*itr == 1) {
cout << "Erase one item of " << *itr << endl;
s.erase(itr++); //在删除之前,迭代器已经指向下一个
} else {
itr++;
}
}

对于序列容器

vector<int> v = {1, 4, 1, 1, 1, 12, 18, 16};
vector<int>::iterator itr2;
for (itr2=v.begin(); itr2!=v.end(); ) {
if (*itr2 == 1) {
cout << "Erase one item of " << *itr2 << endl;
v.erase(itr2++); //这样仍然不安全,删除的元素后面的所有迭代器都失效
} else {
itr2++;
}
}

解决方法:

for (itr2=v.begin(); itr2!=v.end(); ) {
if (*itr2 == 1) {
cout << "Erase one item of " << *itr2 << endl;
itr2 = v.erase(itr2);
} else {
itr2++;
}
} // 1 序列容器和无序容器的erase返回指向删除元素下一个元素的迭代器
// 2. 关联容器的erase不返回东西

总结

  • 序列容器和无序容器使用:it = c.erase(it);
  • 关联容器:c.erase(it++);

使用算法

vector<int> c = {1, 4, 1, 1, 1, 12, 18, 16};

//普通函数
bool equalOne(int e) {
if (e == 1) {
cout << e << " will be removed" << endl;
return true;
}
return false;
}
auto itr = remove_if(c.begin(), c.end(), equalOne);
c.erase(itr, c.end()); //使用bind():
bool equalOne(int e, int pattern) {
if (e == pattern) {
cout << e << " will be removed" << endl;
return true;
}
return false;
}
remove_if(v.begin(), v.end(), bind(equalOne, placeholders::_1, 1)); // Lambda函数:
auto itr = remove_if(v.begin(), v.end(),
[](int e){
if(e == 1) {
cout << e << " will be removed" <<endl; return true;
}
}
);

STL进阶--删除元素的更多相关文章

  1. STL容器删除元素的陷阱

    今天看Scott Meyers大师的stl的用法,看到了我前段时间犯的一个错误,发现我写的代码和他提到错误代码几乎一模一样,有关stl容器删除元素的问题,错误的代码如下:std::vector< ...

  2. c++之STL容器删除元素

    1.删除容器中特定值的元素 如果是容器vector,string,,deque,使用erase-remove 例如:erase-remove 注:因为container没有remove,contain ...

  3. STL中用erase()方法遍历删除元素 .xml

    pre{ line-height:1; color:#f0caa6; background-color:#2d161d; font-size:16px;}.sysFunc{color:#e54ae9; ...

  4. STL中用erase()方法遍历删除元素

    STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.set.map).在使用erase方法来删除元素时 ...

  5. STL 中 使用迭代器删除元素的问题

    在vector中删除,大家都知道,直接erase的话,这种写法很有问题.因为erase(iter)之后iter指针就变成野指针了,此时继续iter++就会出问题. for(auto iter = v. ...

  6. js进阶 9-11 select选项框如何动态添加和删除元素

    js进阶 9-11 select选项框如何动态添加和删除元素 一.总结 一句话总结: 二.js进阶 9-11 select选项框如何动态添加和删除元素 1.案例说明 2.相关知识 Select 下拉列 ...

  7. 怎么删除STL容器的元素

    在STL容器有顺序容器和关联容器两种. 顺序容器删除元素的方法有两种: 1.c.erase(p) 从c中删除迭代器p指定的元素.p必须指向c中一个真实元素,不能等于c.end().返回一个指向p之后元 ...

  8. STL——遍历 删除 set 元素

    ==================================声明================================== 本文版权归作者所有. 本文原创,转载必须在正文中显要地注明 ...

  9. STL容器迭代过程中删除元素技巧(转)

    1.连续内存序列容器(vector,string,deque) 序列容器的erase方法返回值是指向紧接在被删除元素之后的元素的有效迭代器,可以根据这个返回值来安全删除元素. vector<in ...

随机推荐

  1. 九度OJ1153-括号匹配-栈的应用

    题目1153:括号匹配问题 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:9697 解决:4213 题目描述: 在某个字符串(长度不超过100)中有左括号.右括号和大小写字母:规定(与常见 ...

  2. 2018.10.25 CCSP马拉松摸铜归来

    24号体测跑50+1000米. 50米抢跑被罚重跑???然后老年人就只能吊着一口仙气跑第二次50米.然后跑1000米,然后再到宿舍收拾行李赶往地铁站,然后再冲到火车站...(卒) 宾馆,三人挤入二人房 ...

  3. Python知识点整理,基础3 - 字典操作

  4. Js 分别取一个数的百位,十位,个位

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  5. MySQL5.6在线DDL不锁表(在线添加字段)

    解答你也看一下MySQL5.6在线DDL不锁表,现在我有一张1亿的表,需要增加一个字段,假如我让你去增加这个字段,你应该注意什么,具体怎么操作? 操作如下:1.注意磁盘空间(临时表目录 参数 tmpd ...

  6. c的动态内存管理

    在linux系统下使用malloc提示警告,解决方法,加入头文件<stdlib.h> 首先来个基本的例子 int *p=(int *)malloc(sizeof(int));(当mallo ...

  7. sqler sql 转rest api 源码解析(四)macro 的执行

    macro 说明 macro 是sqler 的核心,当前的处理流程为授权处理,数据校验,依赖执行(include),聚合处理,数据转换 处理,sql 执行以及sql 参数绑定 授权处理 这个是通过go ...

  8. Benthos metrcis 说明

    Benthos 按照input, pipeline ,buffer,conditions,ouput 这个几个大类,为我们提供了 方便的分析metrics,支持json 格式同时可以暴露为 stats ...

  9. 初等数论及其应用 (第6版) (Kenneth H.Rosen 著)

    第1章 整数 1.1 数和序列 1.2 和与积 1.3 数学归纳法 1.4 斐波那契数 1.5 整除性 第2章 整数的表示法和运算 2.1 整数的表示法 2.2 整数的计算机运算 2.3 整数运算的复 ...

  10. Python time & datetime模块

    time 模块 时间分为三种格式: 时间戳:表示1970年1月1日之后的秒 结构化时间:元组包含了:年.日.星期等... 格式化字符串:格式可以自定义 时间戳: import time time_st ...