1.迭代器头文件:<iterator>
2.迭代器类型:
1).Input迭代器------------------------------>>>向前读取---------------------------------->>>>>istream
2).Output迭代器--------------------------->>>向前写入----------------------------------->>>>>ostream, inserter
3).Forward迭代器--------------------------->>>向前读写----------------------------------->>>>>
4).Bidirectional迭代器--------------------->>>向前向后读写----------------------------->>>>>List, set, multiset, map, multimap
5).Random Access迭代器---------------->>>随机读取写入----------------------------->>>>>vector, deque, string, array
学习:
(1)Input迭代器
Input迭代器只能一次一次向前读取元素,按此顺序一个一个传回元素值。(Input迭代器只能读取元素一次,如果你复制原有的Input迭代器,使其和原来迭代器同时向前读取元素,则返回的元素可能会不一样。)
Input迭代器的各种操作:
表达式 | 效果 |
---|---|
*iter | 读取实际元素 |
iter->member | 读取实际元素成员 |
++iter | 向前步进(传回新值) |
iter++ | 向前步进(传回旧值) |
iter1==iter2 | 判断迭代器是否相等 |
iter1!=iter2 | 判断迭代是否不等 |
TYPE(iter) | 复制迭代器(copy构造函数) |
(2)Output迭代器
Output迭代器与Input迭代器刚好相反,其作用是将元素的值一个一个写入,即,只能一个元素一个元素地赋值。
Output迭代器的操作:
表达式 | 效果 |
---|---|
*iter=value | 将数值写到迭代器位置 |
++iter | 向前步进(传回新值) |
iter++ | 向前步进(传回旧值) |
TYPE(Iter) | 复制迭代器(copy构造函数) |
(3)Forward迭代器
Forward迭代器是Input和Output迭代器的组合,同时具有Input迭代器的读取功能,还有Output迭代器的写入功能。(和Input迭代不同的是:FOrward迭代器可以多次的指向同一群集的同一元素,并能多次处理同一元素。)
表达式 | 效果 |
*iter | 存取实际元素 |
iter->member | 存取实际元素的成员 |
++iter | 向前步进(传回新值) |
iter++ | 向前步进(传回旧值) |
iter1==iter2 | 判断是否相等 |
iter1!=iter2 | 判断是否不等 |
TYPE() | 产生迭代器(default构造函数) |
TYPE(iter) | 复制构造函数(copy构造函数) |
iter1=iter2 | 赋值 |
(4)Bidirectional(双向迭代器)
Bidirectional迭代器在forward迭代器基础上增加了回头遍历的能力,即支持递减运算符。
表达式 | 效果 |
---|---|
--iter | 向后步退(传回新位置) |
iter-- | 向后步退(传回旧位置) |
(5)Random Access(随机存取迭代器)
Random Access 迭代器在Bidirectional迭代器基础上面增加随机存取能力,即提供迭代器计算能力,能加减偏移量。
以下对象和类别支持RandomAccess迭代器:
*****可随机存取的容器:vector,deque
*****strings(字符串,string,wstring)
*****一般指针(指针)
Random Access 迭代器操作:
算式 | 效果 |
---|---|
iter[n] | 存取索引位置为n的元素 |
iter+=n | 向前跳n个元素存取(如果n为负值,则向后) |
iter-=n | 向后跳n个元素存取(如果n为负值,则向前) |
iter+n | 传回iter之后的第n个元素 |
iter-n | 传回iter之前的第n个元素 |
iter1-iter2 | 传回iter1与iter2之间的距离 |
iter1<iter2 | 判断iter1 是否在iter2 之前 |
iter1>iter2 | 判断iter1是否在iter2 之后 |
iter1<=iter2 | 判断iter1是否不在iter2之后 |
iter1>=iter2 | 判断iter1是否不在iter2之前 |
Vector 迭代器的递增(Increment)和递减(Decrement)
**一般而言,迭代器可以通过递增和递减来得到暂时性迭代器,但是Vector和String 就不行,Vector和String得到是暂时性指针;
(因为Vector迭代器通常被实作为一个一般指针;C++不允许修改基本型别(包括指针)的暂时性,但是struct 和class 则是可以的;因此如果迭代器被实化成指针,则会编译出错,但是如果被实化为class ,则是会编译通过的。deque ,List,Sets,和Maps总是可以编译通过的,因为迭代器不可能被实例化成指针。但是Vector就要取决于实化手法了,通常Vector会被实化为一般指针。)
迭代器相关辅助函数:
(1)advance()可以令迭代器前进;可以使迭代器的位置增加,增加幅度由参数决定。
#include<iterator>
void advance(InputIterator& pos,Dist n);
**使名为pos的Input迭代器步进(步退)n个元素;
**对于Bidirectional迭代器和Random Access迭代器,n可以为负值;
**Dist 是个Template 类型,通常是整数型,因为要进行++,--,<,等操作;
**advance()并不进行是否超序列检查,,所以用时要注意!
(2)distance()可以处理迭代器之间的距离
#include<iterator>
Dist distance(InputIterator pos1,InputIterator pos2);
**传回两个迭代器pos1和pos2之间的距离;
**两个迭代器必须指向同一个容器;
**如果不是Random Access迭代器,则必须pos1要必须能够达到pos2位置;
**会返值Dist 的类型由迭代器决定;
(3)iter_swap()可以交换两个迭代器之间的内容;
#include<algorithm>
void iter_swap(ForwardIterator pos1, FOrwardIterator pos2);
**交换迭代器POS1和POS2的值;
**迭代器型别不必相同,但是所指的值必须可以相互赋值;
迭代器配接器(Iterator Adapters)
(1)Reverse 逆向迭代器
Reverse迭代器是一种配接器,重新定义递增运算、递减运算,使其行为正好倒置;如果你使用这样的迭代器,算法将以逆向次序来处理元素。所有标准容器都允许使用Reverse迭代器来遍历。
(所以这里可以知道为什么前面容器的 rbegin()和rend()得到的值是那样的;
c.rbegin(): 返回逆向迭代器;指向逆向遍历的第一个元素;
c.rend(): 返回逆向迭代器;指向逆向遍历的最后元素的下一个位置;
逆向迭代器与迭代器之间的关系:
rbegin()--------->>>>container::Reverse_iterator (end());
rend()----------->>>>container::Reverse_iterator (begin());
逆向迭代器与正常迭代器之间可以通过base()函数进行转换;base()是逆向迭代器特别的成员函数;
这样大家就可以很清楚的明白逆向迭代器与实际值得位置关系。)
(2)Insert(安插)迭代器
Insert迭代器,用来将“赋值新值”操作转化成“安插新值”操作。算法可以执行Insert而非overwrite。
Inset迭代器操作:
算式 | 效果 |
---|---|
*iter | 无实际操作(传回iter) |
iter=value | 安插value |
++iter | 无实际操作(传回iter) |
iter++ | 无实际操作(传回iter) |
Insert 迭代器分类::::C++提供3种Insert迭代器:back Inserters;front Inserters; general Inserts;
插入迭代器(Insert Iterator),又叫插入器(Inserter),是继上次的反向迭代器之后C++中的又一个迭代器适配器。插入迭代器的主要功能为把一个赋值操作转换为把相应的值插入容器的操作。插入迭代器对标准算法库而言尤其重要。算法库对所有在容器上的操作有个承诺:决不修改容器的大小(不插入、不删除)。有了插入迭代器,既使得算法库可以通过迭代器对容器插入新的元素,又不违反这一承诺,即保持了设计上的一致性。
插入迭代器提供了以下几种操作:*itr,itr++,++itr,itr = value。但实际上,前三种操作为“空操作”(no-op),仅仅返回itr。第四种操作itr = value才是插入迭代器的核心,这个操作通过调用容器的成员函数(push_back(),push_front(),insert(),取决于插入器类型)把value插入到插入器对应容器的相应的位置上。
插入迭代器分为三种类型:尾部插入器(back_insert_iterator),首部插入器(front_insert_iterator)和普通插入器(insert_iterator)。第一种通过调用容器的push_back成员函数来插入元素,因此这种插入器只对vector,list,deque和string有效。 第二种通过调用容器的push_front成员函数来插入元素,因此它只对list和deque有效。第三种通过调用insert成员函数来插入元素,并由用户指定插入位置,它对所有标准的容器类型都有效,因为所有容器都定义了insert成员函数。
Insert 迭代器分类:(cont 代表容器,value代表值,pos 代表迭代器位置)
名称 | Class | 其调用函数 | 其生成函数 | |
---|---|---|---|---|
Back Inserter | back_insert_iterator | push_back(value) | back_inserter(cont) | |
Front Inserter | front_insert_iterator | push_front(value) | front_inserter(cont) | |
General Inserter | insert_iterator | insert(value) | inserter(cont,pos) |
(3)Stream iterators
Stream迭代器是一种迭代器配接器,通过它,你可以把stream当成算法的原点和终点。更明确的说,一个istream迭代器可以用来从input stream中读元素,而一个ostream迭代器可以用来对output stream写入元素。Stream迭代器的一种特殊形式是所谓的stream缓冲区迭代器,用来对stream缓冲区进行直接读取和写入操作。
Ostream迭代器可以被赋予的值写入output stream中。
下表列出ostream迭代器的各项操作:
算式 | 效果 |
---|---|
ostream_iterator<T>(ostream) | 为ostream产生一个ostream迭代器 |
ostream_iterator<T>(ostream,delim) | 为ostream产生一个ostream迭代器,且各元素间以delim为分隔符(delim的型别是const char*) |
*iter | 无实际操作(传回iter) |
iter=value | 将value写到ostream |
++iter | 无实际意义(传回iter) |
iter++ | 无实际意义(传回iter) |
以下实例来展示ostream 迭代器用法:
#include<iostream>
#include<vector>
#include<algorithm>
#include<iterator>
using namespace std;
int main()
{
ostream_iterator<int> intWriter(cout, "\n");
*intWriter = 43;
intWriter++;//无实际操作
*intWriter = 77;
intWriter = -5;
vector<int> coll;
for (int i = 1; i <= 9; ++i)
{
coll.push_back(i);
}
copy(coll.begin(), coll.end(), ostream_iterator<int>(cout, "<"));
cout << endl;
system("pause");
}
输出:
43
77
-5
1<2<3<4<5<6<7<8<9<
istream迭代器是ostream迭代器的拍档,用来从input stream读取元素。透过istream迭代器,算法可以从stream中直接读取数据。istream迭代器的各项操作。产生一个istream迭代器时,必须提供一个input stream作为参数,迭代器从中读取数据。然后它便经由input迭代器的一般接口,利用operator<<读取数据。然而,读取动作有可能失败(可能到达文件尾部,或读取错误),此外算法也要知道区间是否到达终点。为解决这些问题,可以使用一个end_of_stream迭代器,可以利用默认构造函数生成。只要有任何一次读取失败,所有istream迭代器都会变成end_of_stream迭代器,所以进行一次读取后, 应该将istream迭代器和end_of_stream迭代器比较一番。
算式 | 效果 |
---|---|
istream_iterator<T>() | 产生一个end-of-stream迭代器 |
istream_iterator<T>(istream) | 为istream产生一个迭代器 |
*iter | 传回先前读取的值 |
iter->member | 传回先前读取的元素成员 |
++iter | 读取下一个元素,并传回其位置 |
iter++ | 读取下一个元素,传回迭代器指向前一个元素的位置 |
iter1==iter2 | 判断12是否相等 |
iter1!=iter2 | 判断12是否不等 |
#include<iostream>
#include<iterator>
using namespace std;
int main()
{
istream_iterator<int> intReader(cin);
istream_iterator<int> intReaderEOF;
while (intReader != intReaderEOF)
{
cout << "once:" << *intReader << endl;
cout << "once again:" << *intReader << endl;
++intReader;
}
system("pause");
}
输出:字符f导致程序结束。
1 2 3 f 4
once:1
once again:1
once:2
once again:2
once:3
once again:3