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函数相关推荐

  1. C++ 笔记(24)— STL map 类(map实例化、插入、查找、删除)

    1. STL 映射类简介 map 和 multimap 是键-值对容器,支持根据键进行查找,区别在于,后者能够存储重复的键,而前者只能存储唯一的键. 为了实现快速查找, STL map 和 multi ...

  2. vector, list, map在遍历时删除符合条件的元素

    直接看源码,内有详细解释 /* 测试vector, list, map遍历时删除符合条件的元素 本代码测试环境: ubuntu12 + win7_x64 */ #include <iostrea ...

  3. 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 ...

  4. Go 学习笔记(12)— 字典map定义、初始化、读取字典、删除字典、清空字典、map 按 key 进行有序遍历

    Go 中字典也叫做 map , map 是一种无序的键值对的集合. map 最重要的一点是通过 key 来快速检索数据, key 类似于索引,指向数据的值. 1. 字典定义 可以使用内建函数 make ...

  5. vector插入/删除元素

    插入操作: 理论知识 ² vector.insert(pos,elem);   //在pos位置插入一个elem元素的拷贝,返回新数据的位置. ² vector.insert(pos,n,elem); ...

  6. C++ STL 遍历 map 的时候如何删除其中的 element

    首先看一段他人的一段文章:from: http://www.cnblogs.com/super119/archive/2011/10/11/2207541.html 我们通过map的erase(ite ...

  7. 顺序表的插入删除查找遍历

    顺序表的插入删除查找遍历 文章目录 顺序表的插入删除查找遍历 代码 运行结果截图 代码 #define Maxsize 100typedef int ElemType; typedef struct{ ...

  8. c语言数组指定位置插入和删除_玩转C语言链表,单链表/双向链表的建立/遍历/插入/删除...

    最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合, ...

  9. 用c语言实现单链表的初始化,建表,查找,求长度,插入,删除等操作,【YTU+2430+C语言习题+链表建立+插入+删除+输(5)...

    的打印.判断链表是否为空.计算链表长度.插入节点.删除节点.删除整个链表.(2) 线性表adt顺序存储实现中的创建.查找.插入和删除等基本操作及相关算法,线性表adt链式存储实现中单链表.循环链表和双 ...

最新文章

  1. python代码判断两棵二叉树是否相同
  2. 5分钟搞定开机引导界面
  3. 2019年广西大学硕士研究生入学《数据结构与程序设计(817)》考试大纲
  4. django-allauth定制模板(转载)
  5. Linux TCP/IP中L4L3的实现框架:udp recv部分
  6. 完全二叉树基本操作(不含遍历)
  7. WordPress Event Easy Calendar插件多个跨站请求伪造漏洞
  8. 训练千亿参数模型的法宝,昇腾CANN异构计算架构来了~
  9. 在线JSon格式显示工具
  10. Java设计模式-设计模式概述
  11. mysql newid函数_sql随机函数newID()和RAND()详解
  12. FR复选框批量删除(填报)
  13. 启明星win7桌面天气预报软件下载与使用方法(带时间)
  14. 区块链入门笔记(五) —— 加密货币博弈论
  15. 在多媒体计算机系统中图像的颜色是,图像量化位数越大,记录图像中每个像素点的颜色种类就越多。() - 试题答案网问答...
  16. linux系统发育树的构建步骤,使用modeltest-ng和raxml-ng构建ML系统发育树
  17. 测试学习--云测试平台
  18. 自考计算机应用技术题,4月全国自考计算机应用技术试题及答案解析
  19. 服务器开机显示器没反应,老司机教你开机显示器没反应怎么办
  20. 数字孪生——实现工业互联网的利器

热门文章

  1. SpringBoot2.0新特性 - Quartz自动化配置集成
  2. 组合的json文件分隔或者拆分
  3. Solr实现SQL的查询与统计--转载
  4. CentOS下安装JDK7 转载
  5. Lesson 16.1016.1116.1216.13 卷积层的参数量计算,1x1卷积核分组卷积与深度可分离卷积全连接层 nn.Sequential全局平均池化,NiN网络复现
  6. 王石:人生60岁才是开始
  7. 深入理解分布式技术 - 理论基石 CAP
  8. 高并发编程-通过volatile重新认识CPU缓存 和 Java内存模型(JMM)
  9. Redis-13Redis发布订阅
  10. 实战SSM_O2O商铺_25【商品类别】商品类别列表展示从Dao到View层的开发