c++如何遍历删除map/vector里面的元素
新技能Get!
问题
对于c++里面的容器, 我们可以使用iterator进行方便的遍历. 但是当我们通过iterator对vector/map等进行修改时, 我们就要小心了, 因为操作往往会导致iterator失效, 之后的行为都变得不可预知. 比如:
#include <iostream>
#include <vector> using namespace std; int main()
{
vector<int> a = {12, 23, 34, 45, 56, 67, 78, 89}; for (auto iter = a.begin(); iter != a.end(); ++iter) {
if (*iter > 30) {
a.erase(iter);
}
} for (const auto &element : a) {
cout<<element<<endl;
} return 0;
} 输出: 12
23
45
67
89
cplusplus的reference里对 std::vector::erase 的描述是:
Iterators, pointers and references pointing to position (or first) and beyond are invalidated, with all iterators, pointers and references to elements before position (or first) are guaranteed to keep referring to the same elements they were referring to before the call.
只有删除元素前面的iterator还保持有效, 之后的遍历行为不可预知.
解决方案
对于vector, erase会返回下一个iterator, 因此我们可以使用如下的方法:
#include <iostream>
#include <vector> using namespace std; int main()
{
vector<int> a = {12, 23, 34, 45, 56, 67, 78, 89}; auto iter = a.begin();
while (iter != a.end()) {
if (*iter > 30) {
iter = a.erase(iter);
}
else {
++iter;
}
} for (const auto &element : a) {
cout<<element<<endl;
} return 0;
} 输出: 12
23
对于map, 删除iterator只会影响当前的iterator, 因此使用for循环就够了, 比如:
#include <iostream>
#include <map> using namespace std; int main()
{
map<int, int> a = {{1, 12}, {2, 23}, {3, 34}, {4, 45}, {5, 56}, {6, 67}}; for (auto iter = a.begin(); iter != a.end(); ++iter) {
if (iter->second > 30) {
a.erase(iter);
}
} for (const auto &element : a) {
cout<<element.first<<" : "<<element.second<<endl;
} return 0;
} 输出: 1 : 12
2 : 23
但是更推荐的做法是在erase前让iterator指向下一个元素
#include <iostream>
#include <map> using namespace std; int main()
{
map<int, int> a = {{1, 12}, {2, 23}, {3, 34}, {4, 45}, {5, 56}, {6, 67}}; auto iter = a.begin();
while (iter != a.end()) {
if (iter->second > 30) {
a.erase(iter++);
}
else {
++iter;
}
} for (const auto &element : a) {
cout<<element.first<<" : "<<element.second<<endl;
} return 0;
} 输出: 1 : 12
2 : 23
参考资料
http://stackoverflow.com/questions/4645705/vector-erase-iterator
http://stackoverflow.com/questions/4600567/how-can-i-delete-elements-of-a-stdmap-with-an-iterator
c++如何遍历删除map/vector里面的元素的更多相关文章
- 【遍历集合】Java遍历List,Map,Vector,Set的几种方法
关于list,map,set的区别参考http://www.cnblogs.com/qlqwjy/p/7406573.html 1.遍历list @Test public void testList( ...
- 删除map、list集合元素总结
@Testpublic void removeElementFromMap(){Map<Integer, String> test = new HashMap<Integer, St ...
- Java 循环遍历删除set list中的元素
删除List和Set中的某些元素 错误代码的写法: Set<String> set = new HashSet<String>(); set.add("aaaaaa& ...
- map/vector遍历删除
map遍历删除 map<int, vector<int>>::iterator it = g_map.begin(); for (; it != g_map.end(); /* ...
- map,vector 等容器内容的循环删除问题(C++)
map,vector 等容器内容的循环删除问题(C++) map,vector等容器的循环删除不能用普通的方法删除: for(auto p=list.begin();p!=list.end();p++ ...
- Set,List,Map,Vector,ArrayList的区别(转)
JAVA的容器---List,Map,Set Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtab ...
- STL容器的遍历删除
STL容器的遍历删除 今天在对截包程序的HashTable中加入计时机制时,碰到这个问题.对hash_map中的每个项加入时间后,用查询函数遍历hash_map,以删除掉那些在表存留时间比某个阈值长的 ...
- STL中用erase()方法遍历删除元素 .xml
pre{ line-height:1; color:#f0caa6; background-color:#2d161d; font-size:16px;}.sysFunc{color:#e54ae9; ...
- STL中用erase()方法遍历删除元素
STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.set.map).在使用erase方法来删除元素时 ...
随机推荐
- 使用Trello实现敏捷项目管理
使用Trello实现敏捷项目管理 作者 侯伯薇 发布于 五月 24, 2012 | 1 讨论 新浪微博腾讯微 ...
- IOC和AOP使用扩展 多种方式实现依赖注入
多种方式实现依赖注入 1.Spring 使用setter访问器实现对属性的赋值, 2.Spring 构造constructor方法赋值, 3.接口注入 4.Spring P命名空间注入直接量 sett ...
- Delphi 7学习开发控件
我们知道使用Delphi快速开发,很大的一方面就是其强大的VCL控件,另外丰富的第三方控件也使得Delphi程序员更加快速的开发出所需要的程序.在此不特别介绍一些概念,只记录自己学习开发控件的步骤.假 ...
- sqlserver巧用row_number和partition by分组取top数据
SELECT * FROM( SELECT orderid,createtime, ROW_NUMBER() over(PARTITION by orderid order by createtime ...
- java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.TextView
最近在学习drawerLayout时,遇到这个bug.如下示: java.lang.ClassCastException: android.widget.RelativeLayout cannot b ...
- java基础之:堆排序
最近做题目饱受打击,愈发觉得打好基础的重要性,于是乎,决心把基本的排序算法还有数组操作一一实现,目的在于一方面能够得到对JAVA基础的巩固,另一面在实现的过程中发现不足. 今天所实现的堆排序(最大堆) ...
- Java核心知识点学习----使用Condition控制线程通信
一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...
- JS调用BHO
// BHO 中添加下面的函数,设置UIHandler// BHO 包含如下成员变量: // CDocDispatch m_docDispatch;// CComPtr<IDocHostUIHa ...
- Java 第13章 带参数的方法
带参数的方法 无参方法有那几个组成部分? 调用无参方法的两种形式是什么? 第一种:同一个类中的方法调用 直接用方法名 show(): 第二种:不同类中的方法调用 -->对象实例化 -->对 ...
- 【转】JavaScript中,{}+{}等于多少?
原文链接:http://www.2ality.com/2012/01/object-plus-object.html 译文链接:http://www.cnblogs.com/ziyunfei/arch ...