我试着用这样的顺序来取月份:对于一月份,它将以31时间打印1,在二月份将以28时间打印2,等等。
std::vector<int> list = {31, 28, 31, 30, 31, 30, 31, 31, 30, 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中,我尝试使用accumulate函数,但我不能这样做。
任何想法?
对于range-v3,您可以:
std::array<int, 12> days{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 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;
}
}
似乎更清晰。
您可以使用for_each
和fill_n
。
std::ranges::for_each(list, [count = 0](int i) mutable { std::ranges::fill_n(std::ostream_iterator<int>(std::cout, " "), i, ++count); });
您正在寻找的算法是flat_map
。range-v3巧妙地隐藏在for_each
的名字之下。
基本上,我们有transform
(其他一些语言称之为map
) -它接受范围T
和函数T -> U
,并产生范围U
。这是一个1-1映射
我们可以将其推广到一个算法,该算法接受范围T
和函数T -> range_of<U>
,并产生范围U
。而transform
本身会产生U
的范围,我们将结果扁平化。因此,flat_map
.
在range-v3中,看起来像:
views::iota(0u, days_in_month.size())
| views::for_each([&](int month){
return views::repeat_n(month+1, days_in_month[month])
})
或
views::enumerate(days_in_month)
| views::for_each([](auto e){
auto [idx, days] = e;
return views::repeat_n(idx+1, days);
})
演示。