Copy every other element using standard algorithms (downsampling)

前端 未结 4 1305
长情又很酷
长情又很酷 2021-01-22 01:52

say I have a std::vector with N elements. I would like to copy every n-th element of it to a new vector, or average up to that element then copy it (downsample the

4条回答
  •  面向向阳花
    2021-01-22 02:18

    You may have explicitly stated that you prefer not to use Boost, but any non-Boost solution would really be implementing exactly this sort of thing anyway, so I'll show you how I would do it in Boost. Ultimately, I think you're better off writing a simple loop.

    Downsampling uses strided

    boost::copy(
            input | strided(2),
            std::back_inserter(output));
    

    Downsampling average additionally uses transformed, though this solution is non-generic and specifically relies upon vector being contiguous:

    boost::copy(
            input | strided(2) | transformed([](auto& x){
                    return std::accumulate(&x, &x + 2, 0) / 2.;
                }),
            std::back_inserter(output));
    

    Of course that has issues if the input isn't an exact multiple of the stride length, so it'd probably be better to do something like:

    auto downsample_avg = [](auto& input, int n){
        return input | strided(n) | transformed([&,n](auto& x){
            auto begin = &x;
            auto end = begin + std::min(n, &input.back() - begin + 1);
            return std::accumulate(begin, end, 0.0) / (end - begin);
        });
    };
    
    boost::copy(
        downsample_avg(input, 2),
        std::back_inserter(output));
    

提交回复
热议问题