c++stl之反向迭代器用法及注意事项!!!
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++stl之反向迭代器用法及注意事项!!!相关的知识,希望对你有一定的参考价值。
反向迭代器
1.定义:
-
在容器中从尾元素向首元素反向移动的迭代器
-
对于反向迭代器,递增和递减的含义会颠倒过来
-
递增一个反向迭代器会移动到前一个元素
-
递减一个迭代器会移动到下一个元素
注意:除了forward_list容器之外,其他容器都支持反向迭代器
2.使用反向迭代器的相关函数
- rbegin() —指向容器尾元素
- rend()—指向容器首元素之前一个位置
- crbegin()
- crend()
- 下面两个c开头的是反向迭代器的const版本,即不能修改迭代器指向位置的值
3.反向迭代器与正向迭代器的比较
4.反向迭代器应用之逆序打印数组元素
vector<int> vec = { 1,2,3,4,5,6 };
for (auto it = vec.rbegin(); it != vec.rend(); it++)
{
cout << *it << " ";
}
5.反向迭代器应用之递减序
vector<int> vec = { 1,2,3,4,5,6 };
cout << "整理为递减序后,正序打印: " << endl;
sort(vec.rbegin(), vec.rend());
for_each(vec.begin(), vec.end(), [](int val) {cout << val << " "; });
6.反向迭代器需要递减运算符
- 我们只能从既支持++也支持–的迭代器来定义反向迭代器.
- 毕竟反向迭代器的目的是在序列中反向移动。
- 除了forward_list之外,标准容器上的其他迭代器都既支持递增运算,又支持递减运算
- 但是,流迭代器不支持递减运算,因为不可能在一个流迭代器中反向移动
- 因此,不可能从一个forward_list或一个流迭代器创建反向迭代器
7.反向迭代器和其他迭代器之间的关系
- 现在有一个名为line的string容器,里面存放着用逗号分隔的单词表,现在我们需要找到单词表中第一个单词
string line = "bird,dog,duck,pig";
auto comma = find(line.begin(), line.end(), ',');
cout << string(line.begin(), comma) << endl;//这里是一个临时对象
- 如果line中有逗号,那么comma指向当前逗号所在位置,否则它将等于line.end().
- 如果我们希望打印最后一个单词,可以改用反向迭代器
string line = "bird,dog,duck,pig";
auto comma = find(line.rbegin(), line.rend(), ',');
cout << string(line.rbegin(), comma) << endl;//这里是一个临时对象
- 当我们试图打印找到的单词时,最有意思的部分就来了,看起来下面的代码是显然的方法:
//错误:将逆序输出单词的字符
cout << string(line.rbegin(), comma) << endl;//这里是一个临时对象
- 但它会生成错误的输出结果。例如我们输入的是: bird,dog,duck,pig,则这条语句会打印gip
问题所在:
- 我们使用的是反向迭代器,会方向处理string,因此上述输出语句从crbegin()开始反向打印line的内容。
- 而我们希望按正常顺序打印从rcomma开始到line末尾间的字符。但是我们不能直接使用rcomma。
- 因为它是一个反向迭代器,意味着它会朝着string的开始位置移动.
- 需要做的是,将rcomma转换回一个普通的迭代器,能在line中正向移动.
- 我们调用reverse_iterator的base成员函数来完成这一转换,此成员函数会返回其对应的普通迭代器
string line = "bird,dog,duck,pig";
auto rcomma = find(line.crbegin(), line.crend(), ',');
cout << string(rcomma.base(), line.cend())<< endl;//这里是一个临时对象
- 上图中的对象显示了普通迭代器和反向迭代器之间的关系。
- 例如,rcomma和rcomma.base()指向不同的元素,line.crbegin()和line.cend()也是如此。
- 这些不同保证了元素范围无论是正向处理还是反向处理都是相同的。
8.总结:
- 普通迭代器与反向迭代器的关系反映了左闭合区间的特性。
- 关键点在于[line.crbegin(),rcomma)和[rcomma.base(),line.cend())指向line中相同的元素范围。
- 为了实现这一点,rcomma和rcomma.base()必须生成相邻位置而不是相同位置,crbegin()和cend()也是如此.
反向迭代器的目的是表示元素范围,而这些范围是不对称的,这导致一个重要的结果:
当我们从一个普通迭代器初始化一个反向迭代器,或是给一个反向迭代器赋值时,结果迭代器与原迭代器指向的并不是相同的元素。
以上是关于c++stl之反向迭代器用法及注意事项!!!的主要内容,如果未能解决你的问题,请参考以下文章
c++stl之lower_bound,upper_bound和equal_range函数的详细介绍!!!