###STL学习--迭代器
点击查看Evernote原文。
#@author: gr
#@date: 2014-08-23
#@email: forgerui@gmail.com
STL中的迭代器。
###stl学习
|--迭代器
|--类属算法
|--容器
|--vector
|--deque
|--list
|--set
|--map
|--函数对象
|--适配器
|--分配器
一、Contents
1. 输入迭代器
InputIterator要求:
- 可以++
- 可以==
- 可以
cout<<*it;
取值
可以看出,输入迭代器不是指某种类型,而是一系列类型,只要满足上面要求的迭代器都是输入迭代器。
有一种迭代器可以从输入流中读取数据, 称为输入流迭代器。程序不断读取cin输入流,直到找到'x'或者为空时结束。
//使用istream_iterator需要引入#include <iterator>
istream_iterator<char> in(cin);
istream_iterator<char> eos;
find(in, eos, 'x');
2. 输出迭代器
OutputItertor要求:
- 可以++
- 可以
*it = a;
进行赋值, 但无法保证*it
可以获取到其值
输出迭代器不一定要满足==
的条件。
//输出流迭代器是特殊的输出迭代器
ostream_iterator<string> out(ofstream("a.txt"));
3. 前向迭代器
前向迭代器既是输入迭代器又是输出迭代器,所以既可以读数据又可以写数据,并且可以对序列时行单方向的遍历。
可以保存一个前向迭代器,并利用它从同一个位置重新遍历,这样可以实现多次遍历,这使得前向迭代器不仅可以适应单遍扫描算法,还可以适应多遍扫描算法。
4. 双向迭代器
既可以进行前向遍历,也可以进行反向遍历。这种双向遍历的能力在一些算法中至关重要,比如:reverse
就需要双向迭代器。
数组的内置指针类型满足这种情况。容器list
(链表)也要提供双向迭代器。
int a[] = (3, 5, 1, 4, 7);
reverse(&a[0], &a[5]);
list<int> l(&a[0], &a[5]);
reverse(l.begin(), l.end());
5. 随机访问迭代器
这种迭代器更加灵活。可以在序列的任意两个位置进行跳转,这种操作的时间复杂度是常量。
需要随机访问器的算法,如binary_search
,利用序列的升序性,算法时间复杂度为O(log N),其中N为序列长度。而find
的时间复杂度为O(N)。
再比如sort
算法需要随机访问迭代器,而list
无法随机访问,所以sort
不适应于list
,可以调用list
的成员函数。
数组和vector
(向量)和deque
(双端队列)都是可以随机访问。
6. 插入迭代器
将类属算法转入到“插入模式”,而不是“改写模式”。即表达式*i = ...
不再是使位置i处的对象被改写,而是在这个位置进行插入操作,且这个操作是通过容器的成员函数实现的。当输入流或一个容器向另一个容器传递数据时,这种插入操作特别有用。
STL提供3种插入迭代器:
back_insert_iterator<Container> //使用push_back成员函数
front_inert_iterator<Container> //使用push_front成员函数
inert_iterator<Container> //使用insert成员函数
下面看个例子:
vector<int> vector1;
deque<int> deque1(100, 1);
//下面的代码将报错,vector1没有存储空间
copy(deque1.begin(), deque1.end(), vector1.begin());
上面的copy执行到*(vector1.begin()) = *(deque1.begin())
时将报错,但如果使用插入迭代器作为第3个参数,将会自动调用push_back函数,扩展vector1的空间,如下:
copy(deque1.begin(), deque1.end(), back_insert_iterator< vector<int> > (vector1));
为了使插入迭代器更方便,STL定义了类属函数模板back_inserter:
template <typename Container>
inline back_insert_iterator<Container>
back_inserter(Container& x){
return back_insert_iterator<Container>(x);
}
这样copy就可以更简洁,如下:
copy(deque1.begin(), deque1.end(), back_inserter(vector1));
几种迭代器的适应范围:
back_inserter
可以用于vector,deque,list。
front_inerter
可以用于deque,list。(vector没有提供push_front
)
inserter
可以用于所有容器(包括关联容器)
7. 流迭代器
前面已经提及过了,即istream_iterator
和ostream_iterator
,它们两个基本上是一样的用法。
//使用ifstream流构造迭代器
istream_iterator<T> s1(ifstream("a.txt"));
//使用cin标准输入流构造迭代器
istream_iterator<T> s2(cin);
//下面的语句将构造一个空的迭代器,可以用于判断是否结束
istream_iterator<T>()
8. 常量迭代器
常量迭代器就是const_iterator
,它并不是指针不能变,而是迭代器所指的引用值不能变。当变量修饰为const
,其迭代器必须是const_iterator
,否则报编译错误。当迭代器特别复杂时,别忘了可以用auto:-)
。
9. STL容器的迭代器分类
容器 | 迭代器分类 |
---|---|
T a[n] | 随机 |
vector | 随机 |
deque | 随机 |
list | 双向 |
set | 随机 |
multiset | 双向 |
map | 双向 |
multimap | 双向 |
二、Miscellany
@author gr
@mail forgerui@gmail.com
###STL学习--迭代器的更多相关文章
- 标准模板库(STL)学习探究之vector容器
标准模板库(STL)学习探究之vector容器 C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...
- ###STL学习--vector
点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...
- ###STL学习--关联容器
点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...
- ###STL学习--函数对象
点击查看Evernote原文. #@author: gr #@date: 2014-08-13 #@email: forgerui@gmail.com 在stl中,函数对象被大量地使用,用以提高代码的 ...
- ###STL学习--适配器
点击查看Evernote原文. #@author: gr #@date: 2014-08-24 #@email: forgerui@gmail.com STL中的适配器. ###stl学习 |--迭代 ...
- STL学习:STL库vector、string、set、map用法
本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...
- 带你深入理解STL之迭代器和Traits技法
在开始讲迭代器之前,先列举几个例子,由浅入深的来理解一下为什么要设计迭代器. //对于int类的求和函数 int sum(int *a , int n) { int sum = 0 ; for (in ...
- Effective STL 学习笔记 32 ~ 33
Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 31:排序算法
Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
随机推荐
- 第十三章、学习 Shell Scripts 简单的 shell script 练习
简单的 shell script 练习 简单范例 对谈式脚本:变量内容由使用者决定 [root@www scripts]# vi sh02.sh #!/bin/bash # Program: # Us ...
- [css]inline-block
能被父容器居中.能设置高度宽度和margin.不会像table或div那样占一正行……——这就是inline-block——记得这是浏览器默认样式告诉你的.
- sublime Text 3的默认快捷键大全
Ctrl+M 光标跳至对应的括号 Alt+. 闭合当前标签 Ctrl+Shift+A 选择光标位置父标签对儿 Ctrl+Shift+[ 折叠代码 Ctrl+Shift+] 展开代码 Ctrl+KT 折 ...
- 利用HTML5 Geolocation API在百度地图中显示你的位置
代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <met ...
- 多路径配置vlome group共享存储,VG的更新。
1. PV的概念: a) 一块物理磁盘一块物理硬盘在被LVM管理时被称为“物理卷”. b) 在LVM能对其进行管理之前需要在硬盘上产生一些特殊的数据结构,这个过程就是建立 ...
- MapReduce的流程
1. Inputformat会从job的INPUT_DIR目录下读入待处理的文件,检查输入的有效性并将文件切分成InputSplit列表.Job实例可以通过setInputFormatClass(Cl ...
- Css基础-介绍及语法
css 文件后缀.css 基础语法: selector { property:value } 例如: h1 {color:red;font-size:14px;} color:字体颜色 font-s ...
- hbase运维
NoSQL现在风生水起,hbase的使用也越来越广,但目前几乎所有的NoSQL产品在运维上都没法和DB相提并论,在这篇blog中来总结下我们在运维hbase时的一些问题以及解决的方法,也希望得到更多h ...
- [转]SpringMVC日期类型转换问题三大处理方法归纳
http://blog.csdn.net/chenleixing/article/details/45190371 前言 我们在SpringMVC开发中,可能遇到比较多的问题就是前台与后台实体类之间日 ...
- node.js在windows下的学习笔记(4)---同步,异步,回调的概念
Node.js是使用事件驱动的,非阻塞的I/O模型,用于构建快速的,可扩展的网络应用程序. Node.js想解决的问题是:处理输入,输入,高并发 1.阻塞与非阻塞 阻塞也叫同步,是指每一次执行一个操作 ...