问题描述
我尝试以这样的顺序取一天中的一个月:一月它将打印 1 时间为 31,二月将打印 2 时间为 28 等。
std::vector<int> list = {31,28,31,30,31};
int count = 0;
for(int k = 0; k < 12; k++){
for(int i = 0; i < list[k]; i++)
cout << count + 1;
count++;
}
list 保留当月的总天数。
我可以用这个 for 循环来做,但我想在 1 个循环或 range-v3 库中做。在 range-v3 lib 中,我尝试使用累积功能,但我不能这样做。
有什么想法吗?
解决方法
std::ranges::for_each(list,[count = 0](int i) mutable { std::ranges::fill_n(std::ostream_iterator<int>(std::cout," "),i,++count); });
,
使用 range-v3,您可能会这样做:
std::array<int,12> days{ 31,28,31,30,31 };
auto r = days | ranges::view::transform([count = 0](int n) mutable
{
return ranges::view::ints(1,1 + n)
| ranges::view::transform([count = ++count](int){ return count; });
})
| ranges::view::join;
for (auto e : r)
std::cout << e << ' ';
但是
for (int i = 0; i < 12; ++i) {
for (int j = 0; j != days[i]; ++j) {
std::cout << i + 1;
}
}
看起来更清晰。
,您正在寻找的算法是 nutcracker
。哪个 range-v3 巧妙地隐藏在名称 flat_map
下。
基本上,我们有 for_each
(其他一些语言称之为 transform
) - 这需要一个 map
的范围和一个函数 T
并产生一个 {{ 1}}。这是一个 1-1 映射。
我们可以将其推广到采用 T -> U
范围和函数 U
并产生 T
范围的算法。而 T -> range_of<U>
本身会产生 U
的范围,我们将结果展平。因此,transform
。
在 range-v3 中,这看起来像:
U
或
flat_map
Demo。