【C++】反向迭代器(rbegin,rend)(转载)

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

rbegin和rend,很有用!

C++ primer (中文版第四版)第273页

9.3.2 begin和end成员

begin和end操作产生指向容器内第一个元素和最后一个元素的下一个位置的迭代器,如下所示。这两个迭代器通常用于标记包含容器中所有元素的迭代范围。

c.begin() 返回一个迭代器,它指向容器c的第一个元素

c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一个位置

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

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

上述每个操作都有两个不同的版本:一个是const成员,另一个是非const成员。这些操作返回什么类型取决于容器是否为const。如果容器不是const,则这些操作返回iterator或reverse_iterator类型。如果容器是const,则其返回类型要加上const_前缀,也就是const_iterator和const_reverse_iterator类型。

第353页

11.3.3 反向迭代器

反向迭代器是一种反向遍历容器的迭代器。也就是,从最后一个元素到第一个元素遍历容器。反向迭代器将自增(和自减)的含义反过来了:对于反向迭代 器,++ 运算将访问前一个元素,而 -- 运算则访问下一个元素。

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

假设有一个 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 中的相同元素。       反向迭代器用于表示范围,而所表示的范围是不对称的,这个事实可推导出一个重要的结论:使用普通的迭代器对反向迭代器进行初始化或赋值时,所得到的迭代器并不是指向原迭代器所指向的元素。

时间: 2024-10-12 19:19:33

【C++】反向迭代器(rbegin,rend)(转载)的相关文章

反向迭代器

C++ primer (中文版第四版)第273页 9.3.2 begin和end成员 begin和end操作产生指向容器内第一个元素和最后一个元素的下一个位置的迭代器,如下所示.这两个迭代器通常用于标记包含容器中所有元素的迭代范围. c.begin() 返回一个迭代器,它指向容器c的第一个元素 c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一个位置 c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素 c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素

list反向输出 反向迭代器

反向迭代器(rbegin,rend) c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素 c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素前面的位置 每一个容器里面都有Iterator(迭代器),可以从容器的begin位置到end位置,通过++来遍历.同样也有个反向迭代器reverse_iterator,从rbegin(=end-1)到rend(=begin-1)反向遍历,仍然通过++.可见能反向迭代的容器,应该是一个双向链表. 回想一下,所有容器都定义了 beg

Angular系列----AngularJS入门教程04:迭代器过滤(转载)

我们在上一步做了很多基础性的训练,所以现在我们可以来做一些简单的事情喽.我们要加入全文检索功能(没错,这个真的非常简单!).同时,我们也会写一个端到端测试,因为一个好的端到端测试可以帮上很大忙.它监视着你的应用,并且在发生回归的时候迅速报告. 请重置工作目录: git checkout -f step-3 我们的应用现在有了一个搜索框.注意到页面上的手机列表随着用户在搜索框中的输入而变化. 步骤2和步骤3之间最重要的不同在下面列出.你可以在GitHub里看到完整的差别. 控制器 我们对控制器不做

【ThinkingInJava】23、反向迭代器

/** * 书本:<Thinking In Java> * 功能:我们希望在默认的向前迭代器的基础上,添加产生反向迭代器的能力. * 文件:AdapterMethodIdiom.java * 时间:2015年4月8日19:59:01 * 作者:cutter_point */ package Lesson11holdingyourobjects; import java.util.*; class ReversibleArrayList<T> extends ArrayList<

使用__iter__ , 和__reversed__ 实现正、反向迭代器

内置的iter(), reversed()函数可以进行正反向迭代,如果需要定制正反向迭代,要怎么做呢? 事实上iter函数是调用的__iter__方法, reversed,则是调用的__reversed__方法,那么只需要 重写这两个方法即可: 这里演示反向输出浮点列表: #!/usr/bin/env python #coding:utf-8 #@Author:Andy # iter() 使用的是__iter__方法 # reversed() 使用的是__reversed__ 方法 # 所以如果

leetcode_67题——Add Binary(字符串string,反向迭代器reverse_iterator,栈stack)

Add Binary Total Accepted: 39288 Total Submissions: 158078My Submissions Question Solution Given two binary strings, return their sum (also a binary string). For example,a = "11"b = "1"Return "100". Hide Tags Math String Have

一元多项式的乘法与加法运算 【STL-map哈希-map反向迭代器遍历 + 零多项式】

设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式: 输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数.数字间以空格分隔,但结尾不能有多余空格. 输入样例: 4 3 4 -5 2 6 1 -2 0 3 5 20 -7 4 3 1 输出样例: 15 24 -25 22 30 21 -10 20 -21 8 35 6

迭代器失效2~转载

STL的erase()陷阱-迭代器失效总结 阅读目录(Content) 1.list,set,map容器 1.1 正确写法1 1.2 正确写法2 1.3 错误写法1 1.4 错误写法2 1.5 分析 2. vector,deque容器 2.1 正确写法 2.2 注意 3.迭代器失效的情况 3.1 vector 3.2 deque 3.3 list 3.4 slist 3.5 stack 3.6 queue 3.7 priority_queue 3.8 set 3.9 multiset 3.10

Nginx反向代理使用【转载】

最近工作中经常使用nginx,为了能够更好的使用nginx,我搜罗了很多nginx相关的技术文章来读,所以才有了下面以下内容.在此,为文中引用到和参考到的文章提供者表示感谢.如文中相关内容有错误,也欢迎大家留言提出. Nginx的安装与启动 1)pcre安装,支持正则表达式 http://www.pcre.org/ # tar zxvf pcre-7.9.tar.gz # cd pcre-7.9 #./configure # make && make install 2)openssl安装