• Reverse Iterators(逆向迭代器)


           reverse iterator是STL中第三种预定义的迭代器适配器,该迭代器将以逆方向的进行所有的操作,它将递增运算(++)转换为递减运算(--),反之亦然。同时所有的容器都可以通过成员运算符rebegin()和rend()产生出 reverse iterators,也就是说反向迭代器是正向迭代器的适配器。

    例子一

    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
    
    }

  • 相关阅读:
    UVA
    HDU
    manacher求最长回文子串算法
    next数组求最小循环节
    HUST
    廖雪峰Java1-4数组操作-2数组排序
    廖雪峰Java1-4数组操作-1遍历数组
    廖雪峰Java1-3流程控制-9break、continue
    廖雪峰Java-3流程控制-7for循环
    廖雪峰Java1-3流程控制-6 do-while循环
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468422.html
Copyright © 2020-2023  润新知