[C/C++标准库]_[初级]_[删除反转枚举reverse_iterator详解]
程序员文章站
2022-07-15 09:40:14
...
场景
-
std::vector
里有rbegin()
和rend()
反转枚举迭代器,我们可以通过这个反转枚举std::vector<T>::reverse_iterator
进行倒序迭代,问题是当使用反转枚举时如果有需要删除的元素怎么办?vector.erase()
方法的参数只能是索引枚举std::vector<T>::iterator
,不能是反转枚举。
说明
-
索引枚举和反转枚举是存在下标对应关系
-
如图1. 反转枚举整体向右平移一个元素,它左边第一元素就是
.rend()
. 通过reverse_iterator.base()
对应的iterator
是图1所示的垂直对应的。图1:
-
反转枚举转换为索引枚举通过调用
rite.base()
获得索引枚举;而创建反转枚举需要索引枚举作为参数vector<int>::reverse_iterator(ite)
。
-
-
索引枚举和反转枚举对应的元素转换关系:
*rite == *(rite.base()-1) 或者 *ite = *(reverse_iterator(ite)-1) 即都是 *f = *(f1-1)
目的
删除一个反转枚举i
(从左到右位置),我们需要得到下一个反转枚举位置是i-1
。
-
先要转换为索引枚举
i-1
删除:删除索引枚举
i-1
,得到新的索引枚举位置代替了删除的即i-1
auto cite = v.erase(rite.base()-1);
-
把位置
i-1
的顺序枚举转换为反转枚举,它的位置i-1
即我们需要得到的下一个反转枚举位置。rite1 = VII(cite);
例子
//
// main.cpp
// TestVectorErase
//
// Created by sai on 10/19/20.
// Copyright (c) 2020 qixingshi. All rights reserved.
//
#include <iostream>
#include <vector>
using namespace std;
void TestVectorEraseReverseIterator()
{
// 1. 按照索引顺序枚举
cout << "index order" << endl;
vector<int> v = {1,2,3,4,5,6,7,8,9,10};
for (auto ite = v.begin(); ite != v.end(); ite++) {
cout << *ite << " ";
}
cout << endl;
// 2. 按照索引反转枚举
cout << "reverse order" << endl;
for (auto ite = v.rbegin(); ite != v.rend(); ite++) {
cout << *ite << " ";
}
cout << endl;
// 3. 索引顺序偏移量3的枚举值
auto ite = v.begin()+3;
auto offset = ite - v.begin();
cout << "offset: " << offset << " ite: " << *ite << endl;
// 3.1 该索引顺序的枚举对应的反转枚举偏移量和值.
// 3.2 反转枚举的偏移量 = v.size()-索引顺序偏移量.
typedef vector<int>::reverse_iterator VII;
VII rite(ite);
auto qite = rite -1;
auto roffset = rite - v.rbegin();
cout << "roffset: " << roffset << " rite: " << *rite << endl;
cout << "*(rite-1) == *ite : " << boolalpha << (*qite == *ite) << endl;
auto ite1 = rite.base();
cout << *ite1 << endl;
// 3.3 通过使用反转枚举的方法.base()获取对应的索引枚举,但是这个枚举和反转枚举值不一样。
// 需要通过.base()-1获得等值(即相同元素)的枚举。
auto ite2 = rite.base()-1;
cout << *ite2 << endl;
// 4. 删除反转枚举B,通过转换为对应的索引枚举值A1,调用.erase(A1)之后得到的下一个枚举A2,再通过A2
// 创建反转枚举B1, 这个B1就是B的下一个反转枚举。
cout << "========" << endl;
for (auto rite1 = v.rbegin(); rite1 != v.rend(); ) {
if (*rite1 == 3) {
auto cite = v.erase(rite.base()-1);
rite1 = VII(cite);
cout << *rite1 << endl;
}else{
rite1++;
}
}
for (auto rite1 = v.rbegin(); rite1 != v.rend(); rite1++) {
cout << *rite1 << " ";
}
cout << endl;
}
int main(int argc, const char * argv[])
{
// insert code here...
std::cout << "Hello, World!\n";
TestVectorEraseReverseIterator();
getchar();
return 0;
}
输出
Hello, World!
index order
1 2 3 4 5 6 7 8 9 10
reverse order
10 9 8 7 6 5 4 3 2 1
offset: 3 ite: 4
roffset: 7 rite: 3
*(rite-1) == *ite : true
4
3
========
2
10 9 8 7 6 5 4 2 1