过滤范围(循环)遍历从迭代器开始遍历原始序列
Filtered range (circular) traversal starting from iterator over original sequence
假设您有一个容器,并且有一个指向该容器中某些元素的迭代器。要求是循环推进该迭代器但使用过滤器。现在,在序列上创建一个过滤(循环)视图是微不足道的,但是当你只有一个迭代器在原始序列上时,你如何启动遍历?我正在考虑连接两个范围,如下所示:
#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;
int main () {
std::vector< int > xs{ -4, 1, 3, -4, 2, -3, 6, 7, 8, -9, -10 };
auto iter = xs.begin ();
std::advance (iter, 8);
std::cout << *iter << std::endl;
auto lhs = make_subrange (iter, xs.end ());
auto rhs = make_subrange (xs.begin (), iter);
auto is_pos = [](auto x) { return x >= 0; };
auto rng = views::cycle (views::concat (lhs, rhs) | views::filter (is_pos));
auto next = ++rng.begin ();
std::cout << *next << std::endl;
return 0;
}
有没有更简单的方法?
是的,您可以简单地 drop
iter
之前的元素,而不是在 iter
处连接 2 个子范围。
所以这个片段
auto lhs = make_subrange (iter, xs.end ());
auto rhs = make_subrange (xs.begin (), iter);
auto rng = views::cycle (views::concat (lhs, rhs) | views::filter (is_pos));
变成
auto rng = xs | views::cycle
| views::drop(distance(xs.begin(), iter))
| views::filter(is_pos);
请注意,虽然此解决方案 更简单 ,但它循环遍历所有未过滤的元素,并多次应用过滤谓词。您的解决方案可能比这个更高效。
假设您有一个容器,并且有一个指向该容器中某些元素的迭代器。要求是循环推进该迭代器但使用过滤器。现在,在序列上创建一个过滤(循环)视图是微不足道的,但是当你只有一个迭代器在原始序列上时,你如何启动遍历?我正在考虑连接两个范围,如下所示:
#include <iostream>
#include <range/v3/all.hpp>
using namespace ranges;
int main () {
std::vector< int > xs{ -4, 1, 3, -4, 2, -3, 6, 7, 8, -9, -10 };
auto iter = xs.begin ();
std::advance (iter, 8);
std::cout << *iter << std::endl;
auto lhs = make_subrange (iter, xs.end ());
auto rhs = make_subrange (xs.begin (), iter);
auto is_pos = [](auto x) { return x >= 0; };
auto rng = views::cycle (views::concat (lhs, rhs) | views::filter (is_pos));
auto next = ++rng.begin ();
std::cout << *next << std::endl;
return 0;
}
有没有更简单的方法?
是的,您可以简单地 drop
iter
之前的元素,而不是在 iter
处连接 2 个子范围。
所以这个片段
auto lhs = make_subrange (iter, xs.end ());
auto rhs = make_subrange (xs.begin (), iter);
auto rng = views::cycle (views::concat (lhs, rhs) | views::filter (is_pos));
变成
auto rng = xs | views::cycle
| views::drop(distance(xs.begin(), iter))
| views::filter(is_pos);
请注意,虽然此解决方案 更简单 ,但它循环遍历所有未过滤的元素,并多次应用过滤谓词。您的解决方案可能比这个更高效。