list反向输出 反向迭代器

反向迭代器(rbegin,rend)

c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素

c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素前面的位置

每一个容器里面都有Iterator(迭代器),可以从容器的begin位置到end位置,通过++来遍历。同样也有个反向迭代器reverse_iterator,从rbegin(=end-1)到rend(=begin-1)反向遍历,仍然通过++。可见能反向迭代的容器,应该是一个双向链表。

回想一下,所有容器都定义了 begin 和 end 成员,分别返回指向容器首元素和尾元素下一位置的迭代器。容器还定义了 rbegin 和 rend 成员,分别返回指向容器尾元素和首元素前一位置的反向迭代器。与普通迭代器一样,反向迭代器也有常量(const)和非常量(nonconst)类型。图 11.1 使用一个假设名为 vec 的 vector 类型对象阐明了这四种迭代器之间的关系。

图 1 比较 begin/end 和 rbegin/rend 迭代器

假设有一个 vector 容器对象,存储 0-9 这 10 个以升序排列的数字:

vector<int> vec;
for (vector<int>::size_type i = 0; i != 10; ++i)
vec.push_back(i); // elements are 0,1,2,...9

下面的 for 循环将以逆序输出这些元素:



// reverse iterator of vector from back to front
vector<int>::reverse_iterator r_iter;
for (r_iter = vec.rbegin(); // binds r_iter to last element
r_iter != vec.rend(); // rend refers 1 before 1st element
++r_iter) // decrements iterator one element
cout << *r_iter << endl; // prints 9,8,7,...0

虽然颠倒自增和自减这两个操作符的意义似乎容易使人迷惑,但是它让程序员可以透明地向前或向后处理容器。例如,为了以降序排列 vector,只需向 sort传递一对反向迭代器:



// sorts vec in "normal" order
sort(vec.begin(), vec.end());
// sorts in reverse: puts smallest element at the end of vec
sort(vec.rbegin(), vec.rend());

1.反向迭代器需要使用自减操作符

从一个既支持 -- 也支持 ++ 的迭代器就可以定义反向迭代器,这不用感到吃惊。毕竟,反向迭代器的目的是移动迭代器反向遍历序列。标准容器上的迭代器既支持自增运算,也支持自减运算。但是,流迭代器却不然,由于不能反向遍历流,因此流迭代器不能创建反向迭代器。
      2.反向迭代器与其他迭代器之间的关系
      假设有一个名为 line 的 string 对象,存储以逗号分隔的单词列表。我们希望输出 line 中的第一个单词。使用 find 可很简单地实现这个任务:



// find first element in a comma-separated list
string::iterator comma = find(line.begin(), line.end(), ‘,‘);
cout << string(line.begin(), comma) << endl;

如果在 line 中有一个逗号,则 comma 指向这个逗号;否则,comma 的值为 line.end()。在输出 string 对象中从 line.begin() 到 comma 的内容时,从头开始输出字符直到遇到逗号为止。如果该 string 对象中没有逗号,则输出整个 string 字符串。
      如果要输出列表中最后一个单词,可使用反向迭代器:



// find last element in a comma-separated list
string::reverse_iterator rcomma = find(line.rbegin(), line.rend(), ‘,‘);

因为此时传递的是 rbegin() 和 rend(),这个函数调用从 line 的最后一个字符开始往回搜索。当 find 完成时,如果列表中有逗号,那么 rcomma 指向其最后一个逗号,即指向反向搜索找到的第一个逗号。如果没有逗号,则 rcomma 的值为 line.rend()。
      在尝试输出所找到的单词时,有趣的事情发生了。直接尝试:



// wrong: will generate the word in reverse order
cout << string(line.rbegin(), rcomma) << endl;

会产生假的输出。例如,如果输入是:
      FIRST,MIDDLE,LAST
则将输出 TSAL!

图 2 阐明了这个问题:使用反向迭代器时,以逆序从后向前处理 string对象。为了得到正确的输出,必须将反向迭代器 line.rbegin() 和 rcomma 转换为从前向后移动的普通迭代器。其实没必要转换 line.rbegin(),因为我们知道转换的结果必定是 line.end()。只需调用所有反向迭代器类型都提供的成员
函数 base 转换 rcomma 即可:



// ok: get a forward iterator and read to end of line
cout << string(rcomma.base(), line.end()) << endl;

假设还是前面给出的输入,该语句将如愿输出 LAST。

图 2. 反向迭代器与普通迭代器之间的区别

图 2 显示的对象直观地解释了普通迭代器与反向迭代器之间的关系。例如,正如 line_rbegin() 和 line.end() 一样,rcomma 和 rcomma.base() 也指向不同的元素。为了确保正向和反向处理元素的范围相同,这些区别必要的。从技术上来说,设计普通迭代器与反向迭代器之间的关系是为了适应左闭合范围
(第 9.2.1 节)这个性质的,所以,[line.rbegin(), rcomma) 和[rcomma.base(), line.end()) 标记的是 line 中的相同元素。
      反向迭代器用于表示范围,而所表示的范围是不对称的,这个事实可推导出一个重要的结论:使用普通的迭代器对反向迭代器进行初始化或赋值时,所得到的迭代器并不是指向原迭代器所指向的元素。

Reference:

http://blog.csdn.net/kjing/article/details/6936325

http://www.cppblog.com/deep2/archive/2008/10/24/64972.html

时间: 2024-11-18 16:53:54

list反向输出 反向迭代器的相关文章

【C++】输入并反向输出字符串

<pre name="code" class="cpp">// 反向输出字符串 #include<iostream> #include<string.h> using namespace std; void f(char p[]); int main() { char s[50]; cout<<"请输入一个字符串: "; cin>>s; f(s); cout<<"反

反向输出用户录入的字符串

class Program { static void Main(string[] args) { Console.WriteLine("请录入要反向输出的字符或其它"); //将用户输入的字符串,放入字符数组中 char[] str = Console.ReadLine().ToCharArray(); //将素组中的元素反转 Array.Reverse(str); //遍历数组 foreach (var c in str) { Console.Write(c); } Console

实现数组的反向输出

/*******************对数组元素的值进行反向输出实现******************************/ #include<stdio.h> #define MAX_SIZE 10 void Chang_elem_arr(int *x,int n);     //将数组元素进行反向 void Show_elem_arr(int *x);             //将反向的数组打印到屏幕上 int main() { int arr[MAX_SIZE]={1,4,5,

1-3-13:反向输出一个三位数

描述 将一个三位数反向输出. 输入一个三位数n.输出反向输出n.样例输入 100 样例输出 001 1 #include<stdio.h> 2 #include<math.h> 3 int main() 4 { 5 char a[3]; 6 int i; 7 scanf("%s",&a); 8 for(i=2;i>=0;i--) 9 printf("%d",a[i]-'0'); 10 printf("\n")

九九乘方表/数组排序/反向输出字符串

大家好: 今天在逛百度的时候有位芝麻问了个问题,感觉他是一个初学者!把他的代码添枝加叶了一下成了下面几个程序!大家共勉一下吧! 共 五 个方法: <span style="font-size: 18px;">//格式4 * 3 * 2 * 1 = 24</span> <span style="font-size: 18px;">//</span><span style="font-size: 18px;

4.19递归反向输出字符串

Q:编写一个递归函数,实现将输入的任意长度字符串反向输出的功能. #include <iostream> #include<cstdio> using namespace std; print() { char a; cin>>a; if(a!='#') print();//输入字符不是结束标志#,则递归调用print() if(a!='#') cout<<a;//输入字符时不输出# } int main() { printf("input a s

反向输出字符串

//反向输出字符串 public class SwitchOne { public static void main(String[] args) { String aa= "hello"; //字符串 String [] bb=new String[aa.length()];//定义同等长度数组 for(int i=1;i<=bb.length;i++){ bb[i-1]=aa.substring(i-1,i); //截取字符串的每一个字符,并赋值给数组元素 System.ou

rev 反向输出文件内容

1.命令功能 rev 按行反向输出文件内容 2.语法格式 rev  file 3.使用范例 [[email protected] ~]# echo {a..k} >> test [[email protected] ~]# cat test a b c d e f g h i j k [[email protected] ~]# rev test k j i h g f e d c b a [[email protected] ~]# echo {a..k} |rev k j i h g f

Python实用技巧:实现字符串反向输出的5种方法

Python--实现字符串反向输出的5种方法 方法1: for 循环 1 letter_num = list(input('please input some characters:')) 2 list_num = [] 3 def convert_order(): 4 for i in range(len(letter_num)):#根据列表的长度决定遍历的次数 5 list_num.append(letter_num[len(letter_num) - i - 1])#把letter_num