abdfahim
abdfahim

Reputation: 2553

Efficient shifting of vectors

What is the best way for linear shifting of a vector keeping the length same and setting the empty slots to 0, something like what valarray.shift(int n) does.

I can think of a naive way, just wondering if there is a better one

int shift = 2;
std::vector<int> v = {1,2,3,4,5};
std::rotate(v.begin(), v.end() - shift, v.end());
std::fill(v.begin(), v.begin() + shift, 0);

// Input: 1,2,3,4,5
// Output: 0,0,1,2,3

Upvotes: 1

Views: 1474

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409136

You could use std::move instead, as it should probably be a little more "efficient" than std::rotate. Still need the std::fill call though.

Use it like

std::move(begin(v), end(v) - shift, begin(v) + shift);
std::fill(begin(v), begin(v) + shift, 0);

Also if the shift or size of the vector is input from outside the program, then don't forget to add some safety checks (as in the answer by Paolo).

Upvotes: 5

Paolo Irrera
Paolo Irrera

Reputation: 253

I think that can limit to a call to std::copy as it follows:

#include <iostream>
#include <vector>

int main()
{
    const size_t shift {2};
    const std::vector<int> inVec = {1,2,3,4,5};
    std::vector<int> outVec(inVec.size());
    if(inVec.size() - shift > 0)
    {
        const size_t start {inVec.size() - shift};
        std::copy(inVec.begin(), inVec.begin() + start, outVec.begin() + shift);
    }
    for(const auto& val : inVec)
    {
        std::cout << val << " ";
    }
    std::cout << std::endl;
    for(const auto& val : outVec)
    {
        std::cout << val << " ";
    }
    std::cout << std::endl;
}

Upvotes: 2

Related Questions