Reverse Iterators(逆向迭代器)
2016-03-14 22:28
363 查看
reverse iterator是STL中第三种预定义的迭代器适配器,该迭代器将以逆方向的进行所有的操作,它将递增运算(++)转换为递减运算(--),反之亦然。同时所有的容器都可以通过成员运算符rebegin()和rend()产生出 reverse iterators,也就是说反向迭代器是正向迭代器的适配器。
例子一
![](https://img-blog.csdn.net/20160601202826975?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图1 逆向迭代器的位置和所指的值
![](https://img-blog.csdn.net/20160601203047090?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图2 正向迭代器pos和逆向迭代器rpos之间的转换关系
从图1可以看出:
逆向迭代器的positon和逆向迭代器所指的value不是同一个地方,即逆向迭代器value值在逆向迭代器position的后一位”,和反向迭代器相比,正向迭代器的position和所指的值在同一个地方,在实际应用时都是看value,看例子二。
从图2可以看出:
将正向迭代器转换为逆向迭代器时,两个迭代器的position都是相同的,没有发生移动,指向相同的地方。
例子二
例子三
![](https://img-blog.csdn.net/20160601210629373?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图3 正向迭代器和逆向迭代器区间元素
例子三
将逆向迭代器转化为正向迭代器,STL中的成员函数以及部分算法都是只能接受正向迭代器的参数。我们需要利用迭
代器成员函数base()接口完成反向迭代器的转换。
例子四
例子一
void ReverseIterator() { vector<int> iVector; for (int i = 1; i <= 5; ++i) { iVector.push_back(i); } copy(iVector.rbegin(), iVector.rend(), ostream_iterator<int>(cout, " ")); //5 4 3 2 1 cout << endl; }采用了reverse iterator迭代器后,copy()算法可以不用特殊处理,可以将++运算转换为--,将前向遍历改变为后向遍历,该程序反向输出vector中的数字序列,输出结果为:5 4 3 2 1。
两个关系
我们先看两张图,如图1,图2所示:图1 逆向迭代器的位置和所指的值
图2 正向迭代器pos和逆向迭代器rpos之间的转换关系
从图1可以看出:
逆向迭代器的positon和逆向迭代器所指的value不是同一个地方,即逆向迭代器value值在逆向迭代器position的后一位”,和反向迭代器相比,正向迭代器的position和所指的值在同一个地方,在实际应用时都是看value,看例子二。
从图2可以看出:
将正向迭代器转换为逆向迭代器时,两个迭代器的position都是相同的,没有发生移动,指向相同的地方。
例子二
void ReverseIteratorTest2() { vector<int> iVector; for (int i = 1; i <= 5; ++i) { iVector.push_back(i); } //print all elements 1 2 3 4 5 copy(iVector.begin(), iVector.end(), ostream_iterator<int>(cout, " ")); cout << endl; vector<int>::iterator pos = find(iVector.begin(), iVector.end(), 3); vector<int>::reverse_iterator rpos(pos);//intial reverse_iterator with iterator,存在隐式转换 cout <<"*pos " << *pos << endl;//输出结果3 cout <<"*rpos "<< *rpos << endl;//输出结果2 }该例子说明了反向迭代器和正向迭代器实际指向的值是不一样的,并且我们处理反向迭代器的时候都是指实际的value。
base()函数
利用base()函数可以将逆向迭代器转换为正向迭代,逆向迭代器模板类中提供这样的base()函数,完成迭代器转换。namespace std { template <class iterator> class reverse_iterator { ... iterator base() const; ... }; }
例子三
/**************************************************************** *函数名称:TtranslateIterator *功 能:使用Base函数完成逆向迭代器到正向迭代器的转换 *作 者:Jin *日 期:2016年6月1日 ****************************************************************/ void ConvertIterator() { typedef vector<int> IntVector; IntVector coll; for (int i = 1; i <= 9; ++i) { coll.push_back(i); } //output:1 2 3 4 5 6 7 8 9 PrintElements(coll,"list1:"); IntVector::iterator pos = find(coll.begin(), coll.end(), 5); if (pos != coll.end()) { //output: 5 cout << "pos : "<< *pos << endl; } else { cout << "don't find the element with value 5" << endl; } //convert iterator to reverse iterator IntVector::reverse_iterator rpos(pos); //output: 4 cout << "rpos: " << *rpos << endl; //conver reverse iterator to normal iterator IntVector::iterator rrpos; rrpos = (rpos).base(); //output: 5 cout << "rrpos: " << *rrpos << endl; }
逆向迭代器区间设计
逆向迭代器的区间也是“半开原则”,逆向迭代的begin position位于“第一个元素之前”,逆向迭代器end postion位于“最后一个元素”。由于逆向迭代器所指的value都需要后移1位,因此一对逆向迭代器和一对正向迭代器所包围的元素值是相同的(1 2 3 4 5 ),仅遍历顺序相反,如图3所示。图3 正向迭代器和逆向迭代器区间元素
例子三
/**************************************************************** *函数名称:ReverseIterRange *功 能:两个迭代器定义的半开区间,都转换为reverse迭代器后 * 区间内的所有元素亦然都有效,被逆向输出 *作 者:Jin *日 期:2016年6月1日 ****************************************************************/ void ReverseIterRange() { typedef vector<int> IntVector; IntVector coll; for (int i = 1; i <= 9; ++i) { coll.push_back(i); } //output:1 2 3 4 5 6 7 8 9 PrintElements(coll,"list1:"); IntVector::iterator pos1 = find(coll.begin(), coll.end(), 5); if (pos1 != coll.end()) { //output: 5 cout << "begin positon : "<< *pos1 << endl; } else { cout << "don't find the element with value 5" << endl; } IntVector::iterator pos2 = find(coll.begin(), coll.end(), 8); if (pos1 != coll.end()) { //output: 5 cout << "end positon : "<< *pos2 << endl; } else { cout << "don't find the element with value 8" << endl; } cout << "normal sequence: ";//output:5 6 7 copy(pos1, pos2, ostream_iterator<int>(cout, " ")); cout << endl; IntVector::reverse_iterator rEnd(pos1); IntVector::reverse_iterator rBegin(pos2); cout << "reverse sequence: ";//output:7 6 5 copy(rBegin, rEnd, ostream_iterator<int>(cout, " ")); cout << endl; }
逆向迭代器插入
我们知道在逆向迭代器reverseiterator类中有个base()成员函数,对应的成员变量为current,该成员函数的作用就是将逆向迭代器转化为正向迭代器,STL中的成员函数以及部分算法都是只能接受正向迭代器的参数。我们需要利用迭
代器成员函数base()接口完成反向迭代器的转换。
例子四
void ReverseIteratorTest3() { vector<int> iVector; vector<int> iVectorBack; for (int i = 1; i <= 5; ++i) { iVector.push_back(i); iVectorBack.push_back(i); } //print all elements 1 2 3 4 5 copy(iVector.begin(), iVector.end(), ostream_iterator<int>(cout, " ")); cout << endl; //rename type typedef vector<int>::reverse_iterator nReverseIter; typedef vector<int>::iterator nIter; nReverseIter ReIter = iVector.rbegin() + 2;//initial reverse iterator nReverseIter ReIterBack = iVectorBack.rbegin() + 2;//initial reverse iterator //正向迭代器 = (ReIter).base() = current = ReIter + 1 cout <<"*iIter " << *ReIter << endl; //3 cout <<"*((iIter).base()) " << *((ReIter).base()) << endl; //4 // 1 2 3 4 5 //在反向迭代器值为3的位置插入元素(实际插入的4),并返回插入的新位置,更新后的序列1 2 3 99 4 5 -> nIter it = iVector.insert((ReIter).base(), 99); cout << "insert value: " << *it <<endl; //输出结果99 //1 2 3 4 5 删除反向迭代器值为3的元素(实际删除的4),返回未删除的后一个值,更新后的序列1 2 3 5 it = iVectorBack.erase((ReIterBack).base()); cout << "del value : " << *it <<endl; //输出结果5 }
相关文章推荐
- ORACLE SQL-UPDATE、DELETE、INSERT优化和使用技巧分享
- 让你的insert操作速度增加1000倍的方法
- C# 参考之访问关键字:base、this
- SQL Server中的XML数据进行insert、update、delete
- C#基础语法:Base关键字学习笔记
- SQL Server中的XML数据进行insert、update、delete操作实现代码
- 正确使用MySQL INSERT INTO语句
- mysql中insert与select的嵌套使用方法
- 浅析STL中的常用算法
- STL区间成员函数及区间算法总结
- 将表里的数据批量生成INSERT语句的存储过程 增强版
- MySQL中insert语句的使用与优化教程
- js继承 Base类的源码解析
- Insert Date and Time into Access
- 数据库插入数据之select into from与insert into select区别详解
- c++ STL容器总结之:vertor与list的应用
- C++在成员函数中使用STL的find_if函数实例
- MySQL中REPLACE INTO和INSERT INTO的区别分析
- 使用MySQL的LAST_INSERT_ID来确定各分表的唯一ID值
- mysql快速添加百万条记录的语句