点击查看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_iteratorostream_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学习--迭代器的更多相关文章

  1. 标准模板库(STL)学习探究之vector容器

    标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...

  2. ###STL学习--vector

    点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...

  3. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

  4. ###STL学习--函数对象

    点击查看Evernote原文. #@author: gr #@date: 2014-08-13 #@email: forgerui@gmail.com 在stl中,函数对象被大量地使用,用以提高代码的 ...

  5. ###STL学习--适配器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-24 #@email: forgerui@gmail.com STL中的适配器. ###stl学习 |--迭代 ...

  6. STL学习:STL库vector、string、set、map用法

    本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...

  7. 带你深入理解STL之迭代器和Traits技法

    在开始讲迭代器之前,先列举几个例子,由浅入深的来理解一下为什么要设计迭代器. //对于int类的求和函数 int sum(int *a , int n) { int sum = 0 ; for (in ...

  8. Effective STL 学习笔记 32 ~ 33

    Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  9. Effective STL 学习笔记 31:排序算法

    Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

随机推荐

  1. ORA-01078, LRM-00123错误处理

    创建spfile时, 或者在nomount时, 出现下面的问题: SQL> create spfile from pfile; create spfile from pfile * ERROR ...

  2. asp.net webservice 跨域解决方法

    首先需要把[System.Web.Script.Services.ScriptService]前边的注释去掉,放开权限,其次需要在web.config 里<system.web节点下>添加 ...

  3. iOS中的深复制与浅复制

    很多语言中都有深复制浅复制的概念,如C++,ObjC等.简单来说,浅复制就是两个变量指向了同一块内存区域,深复制就是两个变量指向了不同的内存区域,但是两个内存区域里面的内容是一样的. 浅复制示意图: ...

  4. ASP.NET线程与异步

    什么是线程? 线程简单来说就是一种数据结构,用来管理这个程序的执行状态,其中包括 1.线程核心对象->寄存器的状态 2.线程环境块,是一块用户模式下的内存,包含线程的异常处理链的头部.线程的局部 ...

  5. hadoop安装详解

    1.hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统(HDFS,Hadoop Distributed Filesystem)和MapRe ...

  6. 对PostgreSQL xmax的理解

    xmax The identity (transaction ID) of the deleting transaction, or zero for an undeleted row version ...

  7. Oracle DataGuard数据备份方案详解

    Oracle DataGuard是一种数据库级别的HA方案,最主要功能是冗灾.数据保护.故障恢复等. 在生产数据库的"事务一致性"时,使用生产库的物理全备份(或物理COPY)创建备 ...

  8. CRM-BP相关FUNCTION

    获取BP的地址信息:BUPA_ADDRESS_GET_DETAIL 修改BP的信息:CRM_WAP_BP_CHANGE BUTO50存放2个BP之间的关系 获取BP的角色 BAPI_BUPA_ROLE ...

  9. Fragment的使用简单介绍【Android】

    Fragment在实际项目开发中使用的越来越多,如今简介一下 布局文件: <LinearLayout xmlns:android="http://schemas.android.com ...

  10. WebView的应用 持续积累

    在我的项目中载入网页时我们会用到WebView这个控件,关于这个控件的相关的比較有用的API在这里记录一下. 第一 webview 设置javascript可用,  mWebView = (WebVi ...