Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slicing a vector

Tags:

c++

stl

People also ask

Can you slice a vector in C++?

Slicing a Vector in C++Slicing a vector means to make a subvector from a given vector. Given N integers in a vector arr and to positive numbers X and Y, the task is to slice the given vector from index X to Y in a given vector.

How do I slice a vector in R?

To produce a vector slice between two indexes, we can use the colon operator ":". This can be convenient for situations involving large vectors. More information for the colon operator is available in the R documentation.


You'd just use a pair of iterators:

typedef std::vector<int>::iterator vec_iter;

void doSomething(vec_iter first, vec_iter last) {
    for (vec_iter cur = first; cur != last; ++cur) {
       std::cout << *cur << endl;
    }
}

int main() {
   std::vector v();
   for (int i= 0; i < 10; ++i) { v.push_back(i); }

   doSomething(v.begin() + 1, v.begin() + 5);
   doSomething(v.begin() + 2, v.begin() + 4);
   return 0;
}

Alternatively, the Boost.Range library should allow you to represent iterator pairs as a single object, but the above is the canonical way to do it.


I learnt Python before I learnt C++. I wondered if C++ offered slicing of vectors like slicing in Python lists. Took a couple of minutes to write this function that allows you to slice a vector analogous to the way its done in Python.

vector<int> slice(const vector<int>& v, int start=0, int end=-1) {
    int oldlen = v.size();
    int newlen;

    if (end == -1 or end >= oldlen){
        newlen = oldlen-start;
    } else {
        newlen = end-start;
    }

    vector<int> nv(newlen);

    for (int i=0; i<newlen; i++) {
        nv[i] = v[start+i];
    }
    return nv;
}

Usage:

vector<int> newvector = slice(vector_variable, start_index, end_index);

The start_index element will be included in the slice, whereas the end_index will not be included.

Example:

For a vector v1 like {1,3,5,7,9}

slice(v1,2,4) returns {5,7}


Taken from here:

std::vector<myvector::value_type>(myvector.begin()+start, myvector.begin()+end).swap(myvector);

Usage example:

#include <iostream>
#include <vector>

int main ()
{
    std::vector<int> indexes{3, 6, 9};

    for( auto index : indexes )
    {
        int slice = 3;
        std::vector<int> bar{1, 2, 3, 4, 5, 6, 7, 8, 9};
        std::vector<int>( bar.begin() + index - slice, bar.begin() + index ).swap(bar);

        std::cout << "bar index " << index << " contains:";
        for (unsigned i=0; i<bar.size(); i++)
            std::cout << ' ' << bar[i];
        std::cout << '\n';
    }

    return 0;
}

Outputs:

bar index 3 contains: 1 2 3
bar index 6 contains: 4 5 6
bar index 9 contains: 7 8 9

As others have said, you can represent the "slice" as pair of iterators. If you are willing to use Boost, you can use the range concept. Then you will have even begin()/end() member functions available and the whole thing looks a lot like a container.


use boost range adapters. they are lazy:

operator|() is used to add new behaviour lazily and never modifies its left argument.

boost::for_each(v|sliced(1,5)|transformed(doSomething));

doSomething needs to take range as input. a simple (may be lambda) wrapper would fix that.