五、迭代器--迭代器配接器

4.迭代器配接器

c++标准库提供了很多预定义的特殊迭代器,即所谓的迭代器配接器(iterator adapters).
迭代器配接器使算法能够以逆向,安插模式进行工作,还可以和流配合。

1.逆向迭代器

Reverse是一种配接器。他能定义递增运算符和递减运算。使其行为倒置。算法一逆序来处理元素,所有的容器都允许使用reverse迭代器来遍历元素。

reverse_iterator与iterator都继承自_Iterator_base,它们是可以相互转换的。

  • 调用reverse_iterator的base()方法可以获取”对应的”iterator。
  • 可以用iterator构造一个”对应的”reverse_iterator。

例子:

#include<iterator>
void printItem(int elem){
    cout << elem << "   ";
}
--------------省略-------------
    vector<int> vec2 = {1,2,3,4,5,6,7,8};
    vector<int>::iterator  iter=vec.being()+5;


    vector<int> ::reverse_iterator riter(iter);//用iter初始化逆向迭代器
    cout<<"iter:"<<*iter<<endl;
    cout<<"riter: "<<*riter<<endl;

    //正向
    cout << " vec2: ";
    for_each(vec2.begin(), vec2.end(), printItem);
    cout << endl;
    //逆向输出
    cout << " vec2: ";
    for_each(vec2.rbegin(), vec2.rend(), printItem);
    cout << endl;
---------------省略--------------

结果为:

 iter:6
 riter: 5
 vec2: 1   2   3   4   5   6   7   8
 vec2: 8   7   6   5   4   3   2   1

当我们用普通迭代器初始化一个逆向迭代器的时候,我们看iter指向的是6,但是逆向迭代器初始化后指向的却是5.
这是因为:

1. 普通迭代器: begin()指向第一个元素,end()指向末尾元素的后一个位置,区间为左闭右开[first,last)
2. 逆向迭代器的物理位置逻辑位置
 (1). 物理位置: begin() == rend(), end() == rebegin()
 (2). 逻辑位置: 为了保证逆向迭代器和普通迭代器的概念一致性:rbegin()指向end()-1即最后一个元素,rend()指向begin()-1即第一个元素前的位置。这就是逻辑位置

通过图可以看出
1. 反向迭代器的物理位置 为普通迭代器的位置。
2. 反向迭代器的逻辑位置就是普通迭代器的前一个位置

因此,普通迭代器 iter指向 6;
那么iter初初始化逆向迭代器riter的位置为:5;即iter的前一个位置;

【本段内容引用自:C++迭代器之’反向迭代器’


2.插入型迭代器

  1. Insert迭代器为Inserters,用来将“赋值新值”操作转换为“安插新值”操作;
  2. 算法可以执行安插行为而非覆盖行为
  3. 所有Insert迭代器属于Output迭代器类型,只提供赋值能力;

Insert迭代器吧上述的赋值动作转为安插动作

  • 运算符“*”传回迭代器当前的位置
  • 然后由operator=赋值新值

Insert迭代器的技巧:

  • operator*在实际操作中被认为是一个无实际操作的动作,简单传回*this,对Insert迭代器来说,*pospos等价;
  • 赋值动作被转化插入动作;事实上Insert迭代器会调用容器的push_back(),push_front(),insert()等成员函数;

对与一个insert迭代器,插入新值: *pos = value

Insert迭代器的分类:区别在于插入位置

  • 后插入型
  • 前插入型
  • 产生型

分类:

名称class其所调用的函数生成函数
BackInserterback_insert_iteratorpush_backback_inserter(cont)
FrontInserterfonrt_insert_iteratorpush_frontfront_inserter(cont)
GeneralInsterinsert_iteratorInsert(pos,value)Inserter(cont, pos)

容器本身需要支持Insert迭代器所调用的函数,否则该Insert迭代器就不可用;
- back_inserter: 支持vector,deque,list, string·容器
- front_inserter: 支持deque, list 容器

3. 流迭代器

  1. 流迭代器是一种迭代器配接器,可以把流当做算法的原点和终点;
  2. 流迭代器是特殊用途的输入和输出迭代器,程序能管理与I/o相关的数据;
  3. istream 迭代器从input stream中读取元素;ostream迭代器对Output stream写入元素。
  4. 流迭代器的特殊形式:stream缓冲区迭代器
1.ostream迭代器

ostream迭代器将值写入到Output stream中。
ostream迭代器赋值操作转化为运算符operator<<

ostream迭代器的各项工作
算式效果
ostream_iterator<T>(ostream)为ostream产生一个ostream迭代器
ostream_iterator<T>(ostream,delim)为ostream产生一个ostream迭代器,各元素间以delim作为分隔符
*iter无实际操作
Iter = value将value写入到ostream, 如ostream << value
++ iter无实际操作
Iter ++无实际操作

1. 生成迭代器的时候,必须提供一个 outputstream作为参数,迭代器会将元素写入到此Output stream身上;
2. 另一个参数可有可无,是一个字符串,作为元素之间的分隔符。分割符的类型 cosnt char*,如果使用string类型,需要转换,如使用c_str()

例子:

---------------省略-------------------
vector<int> vec2 = {1,2,3,4,5,6,7,8};
cout << " vec2: ";
copy(vec2.begin(), vec2.end(), ostream_iterator<int>(cout," "));
cout << endl;
---------------省略-------------------

结果为:

vec2: 1 2 3 4 5 6 7 8
2. istream迭代器
  1. 用于从input stream中读取元素。
  2. 一般经过从input迭代器的通用接口,利用operator>>读取元素,操作可能失败,算法需要知道终点
  3. 为了解决这个问题: 使用 end-of-stream,他利用istream迭代器默认构造函数生成。
  4. 只要读取失败一次,istream迭代器就变成了end-of-stream,读取结束,可以将两个迭代器进行比较

istream迭代器的操作:

算式效果
istream_iterator<T>()产生一个end-of-stream迭代器
istream_iterator<T>(istream)为istream产生一个istream迭代器(可能立即读取一个元素)
*iter传回先去读取的值(如果构造函数没有读取第一个元素的值,则本式子执行读取任务)
iter->member传回读取元素的成员
++iter读取下一个元素并返回其位置
iter ++读取下一个元素,传回迭代器指向的前一个元素
iter1 == iter2检验 iter1 和iter2是否相等
iter1!= iter2检验iter1 和iter2是否不等

istream迭代器的模板:

template< class T,class CharT = char,
                class Traits = std::char_traits<CharT>, 
                class Distance = std::ptrdiff_t >
class istream_iterator: public std::iterator<std::input_iterator_tag, T, Distance, const T*, const T&>
  1. 第一个参数是数据类型
  2. 第二个和第三个参数确定stream类别
  3. 第四个参数表示指定迭代器距离表示的型别;

两个istream迭代器相等的条件:

  • 两者都是end-of-stream迭代器
  • 两个都可以进行读取操作,并指向相同的stream;

例子:

---------------省略----------------
istream_iterator<int> inputcin(cin);//cin迭代器
istream_iterator<int> eof;//流结束迭代器

while (inputcin != eof){
    vec1.push_back(*inputcin);
    ++inputcin;
}
---------------省略----------------
使用`CTRL + Z`输入空白,结束

结果为:

1 2 3 4 5 6 7  8 9
^Z
 vec1: 1   2   3   4   5   6   7   8   9
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值