【转】失效迭代器(Invalidating Iterators)
vectors: 引起内存重新分配的插入运算使所有迭代器失效,插入也使得插入位置及其后位置的迭代器失效,删除运算使得删除位置及其后位置的迭代器失效.
vector的push_back操作可能没事,但是一旦引发内存重分配,所有迭代器都会失效;
vector的insert操作插入点之后的所有迭代器失效;但一旦引发内存重分配,所有迭代器都会失效;
vector的erase操作插入点之后的所有迭代器失效;
vector的reserve操作所有迭代器失效(因为它导致内存重分配);
list/map: 插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.
deque的insert操作所有迭代器失效;
deque的erase操作所有迭代器失效;
1. 对于关联容器(如map, set, multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。
for (iter = cont.begin(); it != cont.end();)
{
(*iter)->doSomething();
if (shouldDelete(*iter))
cont.erase(iter++);
else
++iter;
}
2. 对于序列式容器(如vector,deque),删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。所以不能使用erase(iter++)的方式,还好erase方法可以返回下一个有效的iterator。
for (iter = cont.begin(); iter != cont.end();)
{
(*it)->doSomething();
if (shouldDelete(*iter))
iter = cont.erase(iter);
else
++iter;
}
3. 对于list来说,它使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的iterator,因此上面两种方法都可以使用。
删除数组中某个元素后连续重复的元素,例如 1,1,2,3,3,1,1,1,4,0 ---> 1, 2,3,1,4,0。给出问题的一个正确的实现:
- #include <iostream>
- #include <vector>
- using namespace std;
- int main(int argc, char* argv[])
- {
- int a[] = {1, 1, 3, 3, 3, 2, 4, 1, 1, 1, 0};
- int size = sizeof(a)/sizeof(a[0]);
- vector<int> vec(a, a+size);
- vector<int>::iterator iter = vec.begin();
- int previous = *iter;
- ++iter;
- for (; iter != vec.end();)
- {
- if(*iter == previous)
- {
- iter = vec.erase(iter);
- }
- else
- {
- previous = *iter;
- ++iter;
- }
- }
- for(iter = vec.begin(); iter != vec.end(); ++iter)
- {
- cout << *iter << endl;
- }
- return 0;
- }
PS. 不过实际上这个问题,用vector来实现不是很适合,因为每次删除一个元素,都会引起vector的一个resize操作。resize的时间复杂度是O(n),整个的resize操作要花费O(n^2)。最好是选择list最为容器,list最适合那些需要在容器中间做插入、删除的例子。
【转】失效迭代器(Invalidating Iterators)的更多相关文章
- C++ 标准模板库(STL)——迭代器(iterators)的用法及理解
C++ STL中迭代器(iterators)用于遍历对象集合的元素.由于容器大小随着插入删除等操作动态改变,无法像静态数组那样获取数组长度然后遍历容器里的所有元素:这时就需要迭代器,每次从容器内第一个 ...
- C++ STL中迭代器失效的问题
my_container.erase(iter); 其中my_container是STL的某种容器,iter是指向这个容器中某个元素的迭代器.如果不是在for,while循环中,这种方式删除元素没有问 ...
- C++中迭代器原理、失效和简单实现
目录 迭代器的使用 迭代器的种类 迭代器的失效 迭代器的实现 1.迭代器的使用 为了提高C++编程的效率,STL中提供了许多容器,包括vector.list.map.set等.有些容器例如vector ...
- 模拟实现简化版List迭代器&嵌入List
1.迭代器(iterators)概念(1)迭代器是一种抽象的设计概念,其定义为:提供一种方法,使他能够按顺序遍历某个聚合体(容器)所包含的所有元素,但又不需要暴露该容器的内部表现方式. (2)迭代器是 ...
- 【OpenMesh】使用迭代器和循环机
原文出处: http://openmesh.org/Documentation/OpenMesh-Doc-Latest/tutorial.html 这个例子展现: 如何使用迭代器 如何使用循环机 这个 ...
- python的迭代器、生成器、装饰器
迭代器.生成器.装饰器 在这个实验里我们学习迭代器.生成器.装饰器有关知识. 知识点 迭代器 生成器 生成器表达式 闭包 装饰器 实验步骤 1. 迭代器 Python 迭代器(Iterators)对象 ...
- STL迭代器------Traits编程技法详细理解(一)
最近在看STL源码解析的迭代器(iterators)一章,涉及到c++ Traits的编程技法,刚开始看时一头雾水,反复看了好几遍之后才理解这个东西,因此来写写在这方面的理解,如有错误,希望读者指正. ...
- 容器vector 迭代器iterator 应用
#include <iostream> #include <vector> using namespace std; int main() { vector<int> ...
- Qt容器类之二:迭代器
一.介绍 遍历一个容器可以使用迭代器(iterators)来完成,迭代器提供了一个统一的方法来访问容器中的项目.Qt的容器类提供了两种类型的迭代器:Java风格迭代器和STL风格迭代器.如果只是想按顺 ...
随机推荐
- DWZ主从表界面唯一性验证(后台验证)(三)
之前的博客介绍了前台自写js来验证主动表的唯一性,除了前台的验证,我也学习了后台的一些判断. 再次介绍一下背景需求: 利用DWZ的主从表结构批量添加课程信息,在提交表单后,触发Action事件 1.是 ...
- notepad++ 文本替换功能,解决excel批量修改数据库的数据操作
^ \(' 开始\t ',' 制表符$ '\) 行末 复制出来之后,使用文本替换功能,转换为SQL,添加到临时表中.然后多表关联修改. SELECT COUNT(*) FROM orderno; # ...
- c++const关键字---15
原创博文,转载请标明出处--周学伟 http://www.cnblogs.com/zxouxuewei/ const是一个C++语言的限定符,它限定一个变量不允许被改变.使用const在一定程度上可以 ...
- [MySQL] 01- Basic sql
准备 一.配置 1. 登录:mysql -u root -p 2. phpMyAdmin创建数据库,并导入.sql文件. 3. 支持中文:set names utf8; 二.面试题 参考:面试宝典- ...
- [Arch] 02. Design principle and Software Pattern
Ref: 软件设计的七大原则 有时间的话,还需进一步深入理解. Figure, 重要的前五个原则 单一职责原则 (Simple responsibility pinciple SRP) 类的设计趋向于 ...
- 8 -- 深入使用Spring -- 3...1 Resource实现类InputStreamResource、ByteArrayResource
8.3.1 Resource实现类------InputStreamResource:访问输入流资源的实现类.ByteArrayResource:访问字节数组资源的实现类. 5. 访问字节数组资源 ⊙ ...
- beautifulsoup4 安装教程
下载beautifulsoup, 下载地址:https://www.crummy.com/software/BeautifulSoup/bs4/download/ 下载完成之后,解压到一个文件夹,用c ...
- Mysql主从热备
mysql主从配置比较不错的文章,大家可以参考下~ https://www.cnblogs.com/kissdodog/p/5422195.html
- mysql和连接相关的timeout
MySQL和连接相关的timeout 今天同事问为什么查询mysql库时, 在数据量比较大时,会话总断.刚开始以为是mysql的和连接有关timeout的问题,结果是网络的不稳定的原因. 下面总结下和 ...
- PostgreSQL存储过程(2)-基于PL/PgSQL的存储过程
介绍 PL/pgSQL 是PostgreSQL 数据库系统的一个可加载的过程语言. PL/pgSQL 的设计目标是创建一种可加载的过程语言,可以 用于创建函数和触发器过程, 为SQL 语言增加控制结构 ...