vector/list/map/set的插入、删除、遍历 - remove\erase函数
1、vector中删除满足某些条件的元素和迭代器失效问题
#include <iostream>
#include <vector>
using namespace std;
int main()
{std::vector<int> mVector;mVector.push_back(1); //插入元素push_backmVector.push_back(2);mVector.push_back(0);mVector.push_back(3);mVector.push_back(4);mVector.push_back(0);mVector.push_back(0);mVector.push_back(6);mVector.push_back(0);mVector.push_back(0);std::vector<int>::iterator iter = mVector.begin();for (; iter != mVector.end(); ) //删除操作{if (0 != *iter){++iter;}else{iter = mVector.erase(iter); //方式一(正确) //mVector.erase(iter++); //方式二(错误)//mVector.erase(it); it++; //方式三(错误)}for (iter = mVector.begin();; iter != mVector.end(); ++iter)//vector遍历操作{std::cout << " " << *iter << " ";}return 0;
}
【错误分析】
/*方式三:错误vv.erase(it); //对vector进行增加删除等操作后之前it可能无效it++; //删除后it此时已经无效,it成为野指针,不能执行it++操作
/*方式二:错误该种情况,vector、deque不能用,但是list、map、set可以!
2、list中删除满足某些条件的元素
#include <iostream>
#include <list>
using namespace std;
int main()
{std::list<int> mList;mList.push_back(1); //插入操作push_backmList.push_back(2);mList.push_back(0);mList.push_back(3);mList.push_back(4);mList.push_back(0);mList.push_back(0);mList.push_back(6);mList.push_back(0);mList.push_back(0);std::list<int>::iterator iter = mList.begin();for (; iter != mList.end(); ) //删除操作{if (0 != *iter){++iter;}else{iter = mList.erase(iter); //方式一(正确)//mList.erase(iter++); //方式二(正确)//mList.erase(iter); iter++; //方式三(错误)}}iter = mList.begin();for (; iter != mList.end(); ++iter) //遍历操作{std::cout << " " << *iter << " ";}return 0;
}
3、map中删除满足某些条件的元素
注意:对map和set等自动排序的容器不应使用remove一类算法
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main(int argc, char* argv[])
{ map<int, string> mapData;
//插入元素方式(四种)mapData.insert(pair<int,string>(0,"aaa"));mapData[1] = "bbb"; mapData.insert(make_pair<int,string>(2,"ccc"));mapData.insert(map<int,string>::value_type(3,"ddd"));for (map<int, string>::iterator it=mapData.begin(); it!=mapData.end(); /*it++*/) //删除操作{ if ((*it).first == 2) { it = mapData.erase(it); //方式一(正确)//mapData.erase(it++); //方式二(正确)//mVector.erase(it); it++; //方式三(错误)} else { it++; } } for (map<int, string>::iterator it=mapData.begin(); it!=mapData.end(); it++) //map遍历输出{cout<<(*it).first<<" "<<(*it).second<<endl; //取值操作方式 (*it).first和(*it).second}return 0;
}
3、set中删除满足某些条件的元素
#include<iostream>
#include<set>
using namespace std;
int main()
{ set<int> s; s.insert(5); //第一次插入5,可以插入 s.insert(1); s.insert(0); s.insert(3); s.insert(5); //第二次插入5,重复元素,不会插入 s.erase(-1); set<int>::iterator it = s.begin(); for(;it != s.end();) //删除操作{if(*it < 2){//it = s.erase(it); //方式一(正确)//s.erase(it++); //方式二(正确)//s.erase(it); it++; //方式三(错误)}elseit++;}for(it = s.begin(); it != s.end(); it++) //遍历操作cout << *it << " "; return 0;
}
综上所述,
对于删除操作:
方式一都正确;
方式三都错误;
方式二vector/deque等顺序容器错误、list/map/set等关联容器正确。>
【重点:remove和erase讲解】
1、 erase一般作为一个container的成员函数,是真正删除的元素,是物理上的删除。
2、作为算法项目组的remove类函数,是逻辑上的删除,将被删除的元素移动到容器末尾,然后返回新的末尾,此时容器的size不变更。
3、项目组容器若有成员函数remove,那么代表的是真正物理意义上的删除元素。
4、若是该容器是vector、string或者deque,应用erase-remove idiom或者erase-remove_if idiom。
5、若是该容器是list,应用list::remove或者list:remove_if成员函数。
6、 若是该容器是一个联合 container,应用asso_con::erase成员函数或者remove_copy_if连络swap等体式格式。
7、有一些斗劲特别的容器具现,比如vector等,暂不推敲。【remove和erase对比】 一般情况下,remove是STL的函数,#include < algorithm >,而erase是容器的成员函数,#include <容器> 。 使用remove不能真正的删除元素!
如果你真的要删除东西的话,可以用下面两种形式:erase-remove、erase。
vector<int> v;
v.erase(remove(v.begin(), v.end(), 99), v.end());//删除容器v中的所有的值为99的元素//[总结]
//使用的固定形式:
//v.erase(remove(v.begin(), v.end(), VALUE), v.end());
//这句的意思是,取得VALUE的位置(位于结尾),然后删除VALUE到原vector结尾的所有元素
// remove all elements from Numbers that match 10 vector<int>::iterator ret = remove(Numbers.begin(), Numbers.end(), 10) ;【解释】原vector { 10 20 10 15 12 7 9 },删除10,会将10后面的元素移动到前面
(注意以下逐个元素对齐,模拟元素在内存中的位置,这样就容易看出变化规律)
原vector
10 20 10 15 12 7 9
遇到第一个10,数组变成
20 10 15 12 7 9
遇到第二个10移动到7 9之后又遇到第三个10于是剩下内存中未移动的7 9
20 15 12 7 9 7 9
遇到第三个10
20 15 12 7 9 7 9
但是,有特例— — list容器**
对于list,因为list有成员函数remove,因此调用list的remove成员函数可以“真的”删除,且比应用erase-remove惯用法更高效!
list<int> li; // 建立一个list// 放一些值进去
li.remove(99); // 除去所有等于99的元素// 真的删除值为99的元素// 所以list的大小可能改变了
vector/list/map/set的插入、删除、遍历 - remove\erase函数相关推荐
- C++ 笔记(24)— STL map 类(map实例化、插入、查找、删除)
1. STL 映射类简介 map 和 multimap 是键-值对容器,支持根据键进行查找,区别在于,后者能够存储重复的键,而前者只能存储唯一的键. 为了实现快速查找, STL map 和 multi ...
- vector, list, map在遍历时删除符合条件的元素
直接看源码,内有详细解释 /* 测试vector, list, map遍历时删除符合条件的元素 本代码测试环境: ubuntu12 + win7_x64 */ #include <iostrea ...
- list(链表)常用成员(顺序容器)----插入push_back,push_front,insert删除pop_back,pop_front,erase,clear遍历begin,end判空empt
转自:https://blog.csdn.net/kyfvc/article/details/8879680 list头文件: #include <list> using namespac ...
- Go 学习笔记(12)— 字典map定义、初始化、读取字典、删除字典、清空字典、map 按 key 进行有序遍历
Go 中字典也叫做 map , map 是一种无序的键值对的集合. map 最重要的一点是通过 key 来快速检索数据, key 类似于索引,指向数据的值. 1. 字典定义 可以使用内建函数 make ...
- vector插入/删除元素
插入操作: 理论知识 ² vector.insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置. ² vector.insert(pos,n,elem); ...
- C++ STL 遍历 map 的时候如何删除其中的 element
首先看一段他人的一段文章:from: http://www.cnblogs.com/super119/archive/2011/10/11/2207541.html 我们通过map的erase(ite ...
- 顺序表的插入删除查找遍历
顺序表的插入删除查找遍历 文章目录 顺序表的插入删除查找遍历 代码 运行结果截图 代码 #define Maxsize 100typedef int ElemType; typedef struct{ ...
- c语言数组指定位置插入和删除_玩转C语言链表,单链表/双向链表的建立/遍历/插入/删除...
最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合, ...
- 用c语言实现单链表的初始化,建表,查找,求长度,插入,删除等操作,【YTU+2430+C语言习题+链表建立+插入+删除+输(5)...
的打印.判断链表是否为空.计算链表长度.插入节点.删除节点.删除整个链表.(2) 线性表adt顺序存储实现中的创建.查找.插入和删除等基本操作及相关算法,线性表adt链式存储实现中单链表.循环链表和双 ...
最新文章
- python代码判断两棵二叉树是否相同
- 5分钟搞定开机引导界面
- 2019年广西大学硕士研究生入学《数据结构与程序设计(817)》考试大纲
- django-allauth定制模板(转载)
- Linux TCP/IP中L4L3的实现框架:udp recv部分
- 完全二叉树基本操作(不含遍历)
- WordPress Event Easy Calendar插件多个跨站请求伪造漏洞
- 训练千亿参数模型的法宝,昇腾CANN异构计算架构来了~
- 在线JSon格式显示工具
- Java设计模式-设计模式概述
- mysql newid函数_sql随机函数newID()和RAND()详解
- FR复选框批量删除(填报)
- 启明星win7桌面天气预报软件下载与使用方法(带时间)
- 区块链入门笔记(五) —— 加密货币博弈论
- 在多媒体计算机系统中图像的颜色是,图像量化位数越大,记录图像中每个像素点的颜色种类就越多。() - 试题答案网问答...
- linux系统发育树的构建步骤,使用modeltest-ng和raxml-ng构建ML系统发育树
- 测试学习--云测试平台
- 自考计算机应用技术题,4月全国自考计算机应用技术试题及答案解析
- 服务器开机显示器没反应,老司机教你开机显示器没反应怎么办
- 数字孪生——实现工业互联网的利器
热门文章
- SpringBoot2.0新特性 - Quartz自动化配置集成
- 组合的json文件分隔或者拆分
- Solr实现SQL的查询与统计--转载
- CentOS下安装JDK7 转载
- Lesson 16.1016.1116.1216.13 卷积层的参数量计算,1x1卷积核分组卷积与深度可分离卷积全连接层 nn.Sequential全局平均池化,NiN网络复现
- 王石:人生60岁才是开始
- 深入理解分布式技术 - 理论基石 CAP
- 高并发编程-通过volatile重新认识CPU缓存 和 Java内存模型(JMM)
- Redis-13Redis发布订阅
- 实战SSM_O2O商铺_25【商品类别】商品类别列表展示从Dao到View层的开发