对连续整数块求和的 C++ 算法

Kyl*_*leL 6 c++

给定一个块大小N和一个长度整数向量k * N(可以将其视为k整数块)N,我想创建一个新的长度向量,k其元素是原始向量块的总和。

例如,块大小为 2,向量{1,2,3,4,5,6}将给出结果{3,7,11}

例如,块大小为 3,向量{0,0,0,1,1,1}将给出结果{0,3}

一个简单有效的方法:

std::vector<int> sum_blocks(int block_size, const std::vector<int>& input){
    std::vector<int> ret(input.size() / block_size, 0);

    for (unsigned int i = 0; i < ret.size(); ++i)
    {
        for(unsigned int j=0; j < block_size; ++j)
        ret[i] += input[block_size * i + j];
    }
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

不过,我有兴趣知道是否有更简洁或更有效的方法来执行此操作,可能使用该algorithm库。

cig*_*ien 10

如果您可以使用 range-v3 库,您可以编写如下函数:

namespace rv = ranges::views;
namespace rs = ranges;

auto sum_blocks(int block_size, std::vector<int> const & input)
{
  return input 
         | rv::chunk(block_size) 
         | rv::transform([](auto const & block) {
             return rs::accumulate(block, 0);
           }) 
         | rs::to<std::vector<int>>;
}
Run Code Online (Sandbox Code Playgroud)

这是非常不言自明的,并且避免了像block_size * i + j那样容易出错的算术。

演示

  • 对于那些想知道这些“|”运算符的人,请参阅[范围适配器闭包对象](https://en.cppreference.com/w/cpp/ranges) (2认同)