jsl*_*lap 5 c++ range-v3 c++17
我正在尝试使用 range-v3 库生成无限范围的整数。我的目标是 {0,0,0,1,1,1,2,2,2,0,0,0,1,1,1 ...}。我希望每个数字重复的次数也是可变的。没有这个限制,我可以做到这一点,而且效果很好。
const std::vector<std::vector<int>> repvec = { {0,0,0},{1,1,1},{2,2,2} };
auto joinedVec = repvec | ranges::view::join;
auto infiniteVec = joinedVec | ranges::view::cycle;
Run Code Online (Sandbox Code Playgroud)
但如果我想要可变的重复次数,我就无法编译它:
int nbRep = 3;
const std::vector<int> origVec = { 0, 1, 2 };
auto repVec = origVec | ranges::view::transform( [nbRep] (const int &x) {
return ranges::view::repeat(x) | ranges::views::take(nbRep);
});
auto joinedVec = repVec | ranges::view::join;
auto infiniteVec = joinedVec | ranges::view::cycle;
Run Code Online (Sandbox Code Playgroud)
我不确定这是否是范围库的限制或者我是否做错了什么。
我真的不明白你为什么要这样做:
ranges::view::repeat(x) | ranges::views::take(nbRep)
Run Code Online (Sandbox Code Playgroud)
而不仅仅是:
ranges::view::repeat_n(nbRep)
Run Code Online (Sandbox Code Playgroud)
解决方案非常简单:
auto generate_range(const std::vector<int>& original, const std::size_t reps) {
using namespace ranges;
auto rng = original | views::transform([reps](const auto arg) {
return views::repeat_n(arg, reps);
});
return rng | views::cycle | views::join;
}
Run Code Online (Sandbox Code Playgroud)
我们首先根据向量创建一系列范围original
- 我们将其元素转换为重复元素的范围。我们最终得到一个范围,其中的元素是由重复值组成的范围。根据您的示例,我们有:
rng = [[0, 0, 0], [1, 1, 1], [2, 2, 2]]
Run Code Online (Sandbox Code Playgroud)
现在我们只需要循环所有元素即可。我们最终得到:
rng | cycle = [[0, 0, 0], [1, 1, 1], [2, 2, 2], [0, 0, 0], [1, 1, 1], ...]
Run Code Online (Sandbox Code Playgroud)
我们需要对join
他们做的最后一件事是:
rng | cycle | join = [0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, ...]
Run Code Online (Sandbox Code Playgroud)
完整示例:
#include <iostream>
#include <range/v3/all.hpp>
#include <vector>
auto generate_range(const std::vector<int>& original, const std::size_t reps) {
using namespace ranges;
auto rng = original | views::transform([reps](const auto arg) {
return views::repeat_n(arg, reps);
});
return rng | views::cycle | views::join;
}
int main() {
using namespace ranges;
const std::vector<int> original = {0, 1, 2};
const int reps = 3;
for (const auto r : generate_range(original, reps) | ranges::views::take(15)) {
std::cout << r << ' ';
}
}
Run Code Online (Sandbox Code Playgroud)
打印:0 0 0 1 1 1 2 2 2 0 0 0 1 1 1
.
归档时间: |
|
查看次数: |
1071 次 |
最近记录: |