求Scala中Seq.grouped的C++惯用等价实现(类似std::algorithm)
C++中实现Scala风格的
.grouped分组方法(基于标准库) 你的循环实现本身简洁高效,但如果想贴合标准库惯用写法,这里提供几种基于std::algorithm或C++20范围库的方案,可将序列分割为指定大小的分组,最后一组长度允许小于指定值:
方案1:利用std::generate_n实现
通过std::generate_n批量生成分组,结合迭代器步进截取子序列,逻辑和你的原始实现一致,但更贴合标准库算法风格:
#include <algorithm> #include <vector> #include <iterator> std::vector<std::vector<uint64_t>> chunked; std::vector<uint64_t> flat; // 假设已完成数据填充 const size_t chunk_size = 7; // 预计算分组数量并预留空间,避免频繁内存分配 const size_t num_chunks = (flat.size() + chunk_size - 1) / chunk_size; chunked.reserve(num_chunks); auto it = flat.begin(); std::generate_n(std::back_inserter(chunked), num_chunks, [&]() { // 计算当前分组的结束迭代器,避免越界 const auto remaining = static_cast<size_t>(std::distance(it, flat.end())); auto end_it = std::next(it, std::min(chunk_size, remaining)); // 构造当前分组并更新迭代器位置 std::vector<uint64_t> chunk(it, end_it); it = end_it; return chunk; });
方案2:C++20 范围库(Ranges)优雅实现
如果项目支持C++20,std::views::chunk完全对应Scala的.grouped方法,返回惰性求值的视图(和Scala返回Iterator的行为一致),无需提前复制元素,性能更优:
#include <ranges> #include <vector> #include <iterator> std::vector<uint64_t> flat; // 假设已完成数据填充 const size_t chunk_size = 7; // 生成惰性分组视图,仅在遍历时生成子范围 auto grouped_view = flat | std::views::chunk(chunk_size); // 若需要将分组物化(转为vector的vector) std::vector<std::vector<uint64_t>> chunked(grouped_view.begin(), grouped_view.end());
补充说明
你的原始循环实现其实已经非常高效——直接操作迭代器、无多余开销,且可读性极佳。如果不需要刻意追求“纯标准库算法调用”的写法,完全可以保留原始实现。
内容的提问来源于stack exchange,提问作者Ben Morse
相关产品推荐
相关产品推荐

