删除STL容器中的元素
有关stl容器删除元素的问题,错误的代码如下:
std::vector<struct> mFriendList;
...
std::vector<struct>::iterator iter = mFriendList.begin();
for ( ; iter != mFriendList.end(); ++iter)
{
if (...)
mFriendList.erase(iter);
}
记得当时Once给我说过这个问题,还给我改过代码,我当时不明白为什么,只知道程序执行的时候如果if为true那么程序就肯定会崩溃。
大师的说法是:当容易中的一个元素被删除时,指向该元素的所有迭代器都变得无效。上面的代码中,只要执行了erase(iter),那么iter就会变得无效,那么执行++iter就肯定会出错。
在网上看到有人总结如下两条:
1. 对于节点式容器(map, list, set)元素的删除,插入操作会导致指向该元素的迭代器失效,其他元素迭代器不受影响
2. 对于顺序式容器(vector,string,deque)元素的删除、插入操作会导致指向该元素以及后面的元素的迭代器失效
总结了一下,并回想Once当时给我改的代码,所以正确的写法应该是这样的:
1.
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <iterator> using namespace std; int main(int argc, char* argv[])
{
vector<int> MyList; for (int i = ; i < ; i++)
{
MyList.push_back(i);
} vector<int>::iterator Itor = MyList.begin(); for (;Itor != MyList.end();)
{
if ( *Itor == )
{
Itor = MyList.erase(Itor);
}
else
{
Itor++;
}
} copy(MyList.begin(), MyList.end(), ostream_iterator<int>(cout, " ") );
cout<<endl; return ;
}
2.对于节点式容器
//下面其它的总结, 写法有点怪
std::list<struct> mList;
...
std::list<struct>::iterator iter = mList.begin();
for ( ; iter != mList.end(); )
{
if (...)
{
//因为节点式只会导致当前节点迭代器失效,所以删除节点的同时对迭代器进行后移的操作,因为其他元素不会失效
mList.erase(iter++);
}
else
{
++iter;
}
}
3.对于顺序式容器
std::vector<struct> mVector;
...
std::vector<struct>::iterator iter = mVector.begin();
for ( ; iter != mVector.end(); )
{
if (...)
{
//这里就比较有说法了,因为顺序式容器会使本身和后面的元素迭代器都失效,所以不能简单的++操作
//这里顺序式容器的erase()会返回紧随被删除元素的下一个元素的有效迭代器
//而节点式容器的erase()的返回值是void,这点我感觉太神奇了,确实太神奇了!!!!
iter = mVector.erase(iter);
}
else
{
++iter;
}
}
注意:容器看具体STL库的实现了,VS中两类容器的earse都返回下一个迭代器指针。
删除STL容器中的元素的更多相关文章
- 删除 list 集合中的元素
删除 list 集合中的元素,当删除的元素有多个的时候,只能使用迭代器来删除. 当删除 list 集合中的元素只有一个的时候,有三种方法都可以实现. import java.util.ArrayLis ...
- 怎么删除STL容器的元素
在STL容器有顺序容器和关联容器两种. 顺序容器删除元素的方法有两种: 1.c.erase(p) 从c中删除迭代器p指定的元素.p必须指向c中一个真实元素,不能等于c.end().返回一个指向p之后元 ...
- [Flex] Accordion系列-动态添加或删除Accordion容器中项目
<?xml version="1.0" encoding="utf-8"?> <!--Flex中如何使用addChild()和removeCh ...
- c++随机排序容器中的元素
在各种程序语言中都提供了将容器元素随机排序的shuffle方法,c++也不例外. 不过c++将shuffle放在了<algorithm>中而不是像其他语言一样在random里,同时c++1 ...
- 定时脚本删除docker容器中内容
今天在我同步mongo数据库的时候,服务器的磁盘突然就被占满了导致同步中断,mongo容器也停止工作了.然后就想要弄一个能够定时清理同步过程中留存在docker容器中的mongo数据的脚本.话不多说, ...
- 删除JavaScript对象中的元素
参考http://stackoverflow.com/questions/208105/how-to-remove-a-property-from-a-javascript-object 通过dojo ...
- 删除map容器中指定的元素
for (std::map<Int64,Int64>::iterator iter = ips_forbidden_.begin(); iter != ips_forbidden_.end ...
- 如何删除PHP数组中的元素,并且索引重排(unset,array_splice)?
如果要在某个数组中删除一个元素,可以直接用的unset,但是数组的索引不会重排: <?php $arr = array('a','b','c','d'); unset($arr[1]); pri ...
- 如何删除JAVA集合中的元素
经常我们要删除集合中的某些元素.有些可能会这么写. public void operate(List list){ for (Iterator it = list.iterator(); it.has ...
随机推荐
- 编程语言 - 大数据 - Hadoop
Hive - 特例函数 rlike
- Tcp协议介绍
前情提要:根据域名建立tcp链接之前要做两件事情,1 根据arp协议找到网管mac地址 2 通过dns服务器解析出域名的Ip地址,解析出域名的Ip地址之后就可以建立tcp链接了. tcp协议三个特点: ...
- stl应用(map)或字典树(有点东西)
M - Violet Snow Gym - 101350M Every year, an elephant qualifies to the Arab Collegiate Programming C ...
- 解决Linux下编译.sh文件报错 “[: XXXX: unexpected operator”
本人经常在Linux通过编译 .sh文件来生成工程,之前一直都没问题,代码一直都没变,但是今天编译的时候,却提示错误:
- Centos 7.6安装mysql服务端5.7
环境:centos 7.6,mysql server 5.7.26 新建文件夹/opt/mysql,并cd进去 运行wget http://dev.mysql.com/get/mysql-5.7.26 ...
- 分布式ID增强篇--优化时钟回拨问题
原生实现 本文承接sharding-jdbc源码之分布式ID,在这篇文章中详细介绍了sharding-jdbc的分布式ID是如何实现的:很遗憾的是sharding-jdbc只是基于snowflake算 ...
- 在vue中设计一个客户签名的功能
直接贴代码: <template> <div class="hello"> <p>签字:</p> <canvas id=&qu ...
- MapReduce数据格式化------<一>
引言: 我们知道:在MapReduce程序的Map阶段,需要有数据输入,而由于数据往往大小不规则,所以在数据输入Mapper之前,需要根据数据的特点和业务逻辑对数据进行格式化.这一步的格式化被称为:I ...
- JavaScript—— 案例:表单验证
QQ号:<input type="text" id="txtQQ"><span></span><br> 邮箱:& ...
- textarea实现高度自适应
css部分 #textarea { display: block; margin:0 auto; overflow: hidden; width: 550px; font-size: 14px; he ...