Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ algorithm to sum contiguous blocks of integers

Tags:

c++

Given a block size N and a vector of integers of length k * N which can be viewed as k blocks of N integers, I want to create a new vector of length k whose elements are the sums of the blocks of the original vector.

E.g. block size 2, vector {1,2,3,4,5,6} would give a result of {3,7,11}.

E.g. block size 3, vector {0,0,0,1,1,1} would give a result of {0,3}.

A simple approach that works:

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;
}

However I'd be interested in knowing if there is a neater or more efficient way of doing this, possibly using the algorithm library.

like image 212
KyleL Avatar asked Oct 31 '21 16:10

KyleL


1 Answers

If you can use the range-v3 library, you could write the function like this:

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>>;
}

which is quite self-explanatory, and avoids doing any arithmetic like block_size * i + j, which is error prone.

demo.

like image 109
cigien Avatar answered Nov 14 '22 22:11

cigien