【问题标题】:C++20: How to split range by size?C++20:如何按大小分割范围?
【发布时间】:2021-04-03 06:49:03
【问题描述】:

我想将范围 {1, 2, 3, 4, 5} 拆分为 任何大小> 的子范围(例如,大小为 2:{{1, 2}, {3, 4}, {5}})。 然而std::views::split 仅按分隔符分割。

有没有标准的“反向连接”或者什么可以做到这一点?

【问题讨论】:

  • 据我所知,没有。循环遍历它们并创建新数组..
  • Std::ranges 派生自 range_v3。您可以查看该库是否提供您想要的内容。但是,您的用例似乎不是很普遍,所以可能不是。您始终可以实现自己的扩展。

标签: c++ range c++20 std-ranges


【解决方案1】:

range-v3 将此算法称为chunk。 C++20 中没有这样的范围适配器,但它是为C++23 提议的同名集合的一部分。 For example:

#include <vector>
#include <range/v3/view/chunk.hpp>
#include <fmt/format.h>
#include <fmt/ranges.h>

int main() {
    std::vector v = {1, 2, 3, 4, 5};
    fmt::print("{}\n", v | ranges::views::chunk(2)); // prints {{1, 2}, {3, 4}, {5}}
}

这似乎是该算法跨语言的一个相当一致的名称选择。 Python 有chunked,Rust 有chunks,Swift 有chunks(ofCount: n),D 有chunks,等等

【讨论】:

  • 我会提到,如果 OP 的兴趣不仅仅是用花括号打印到屏幕上(他们询问拆分范围,而不是拆分范围并回显到终端),那么在开发时,他们可以如果他们真的需要打印东西,更容易依赖于为 Range-v3 的范围重载的类 &lt;&lt;
  • @Enlico 呃,什么?是的,我知道他们询问“拆分范围,不拆分范围并回显到终端”,但后者显然需要能够执行前者,并且是验证结果的最方便方法。是否有人怀疑我提出的解决方案实际上符合 OP 的要求?
  • 不,不,解决方案确实回答了这个问题。我只是暗示您可以删除最后两个非标准标题以支持标准#include &lt;iostream&gt;,并使用简单的std::cout &lt;&lt; (v | ranges::views::chunk(2)) &lt;&lt; std::endl; 打印结果。这显然会导致 [[1,2],[3,4],[5]] 带有方括号,而不是花括号,但可能 OP 对这个装饰细节并不真正感兴趣。
  • 是的,@Enlico 有重点。 fmt 是一个不同的主题,也许不应该用于范围的回答。然而,我现在对它没有任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
  • 2021-06-22
相关资源
最近更新 更多