给定C++范围内的绑定迭代器,反向迭代



假设我有一个向量std::vector<int> nums;,我有两个迭代器lower_boudupper_bound。我想在不使用循环或分配任何内存的情况下,将函数应用于数字的同时,将numsupper_bound遍历到lower_boud。我找到了std::transform,但我不知道如何反向遍历。

可以使用std::reverse_iterator来更改任何双向迭代器的方向。请注意,std::transform(b,e,...)需要b<=e,因此必须交换反向迭代器的位置。

#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> nums{1, 2, 4, 5, 6, 7, 8, 9};
auto lb = std::lower_bound(nums.begin(), nums.end(), 2);
auto ub = std::upper_bound(nums.begin(), nums.end(), 8);
std::vector<int> out1;
std::cout << "FORWARDn";
std::transform(lb, ub, std::back_inserter(out1), [](const auto& e) {
std::cout << "Transforming forward:" << e << 'n';
return e;
});
std::cout << "REVERSEDn";
std::vector<int> out2;
std::transform(std::reverse_iterator(ub), std::reverse_iterator(lb),
std::back_inserter(out2), [](const auto& e) {
std::cout << "Transforming backward:" << e << 'n';
return e;
});
}

输出:

FORWARD
Transforming forward:2
Transforming forward:4
Transforming forward:5
Transforming forward:6
Transforming forward:7
Transforming forward:8
REVERSED
Transforming backward:8
Transforming backward:7
Transforming backward:6
Transforming backward:5
Transforming backward:4
Transforming backward:2

std::transform是错误的标准算法,如果您只想迭代元素,因为它需要另一个迭代器来插入转换后的结果(目标需要额外的内存(。相反,std::for_eachstd::reverse_iterator是你的朋友。注意,当你想从ub迭代到lb时,你需要使用反向的ub作为起始索引,反向的lb作为结束索引(这部分采用了Quimby的答案(:

std::for_each(std::reverse_iterator(ub), std::reverse_iterator(lb), f);

其中CCD_ 18是要应用的函数。

另一种方法是直接从std::vector:中搜索正确的迭代器

auto lb = std::lower_bound(v.rbegin(), v.rend(), maxValue, std::greater<int>());
auto ub = std::upper_bound(v.rbegin(), v.rend(), minValue, std::greater<int>());
std::for_each(lb, ub, f);

请注意,这里应用的下界和上界的定义与这些边界的自然感觉相矛盾——在反向比较的意义上——std::greater(!(——它们仍然是正确的(从两种边界查找算法的角度来看,在这个特定上下文中,较大的值被视为小于(,因此,反向的最小值/最大值也是正确的。出于同样的原因/在同样的意义上——就像使用std::vector的反向迭代器一样——我们可以正常地从"lower"迭代到"upper"。

最新更新