Smart way to split a vector into smaller overlapping vectors?

I am currently looking for a way in which i can split a vector into a number of smaller vectors. I am basically trying to implement a sliding window function for a vector.


I found this implementation

1
2
3
4
5
6
7
 std::vector<double>::iterator it;
 for(it = vec.begin(); (it+(NUM_SECONDS*SAMPLE_RATE)) !=vec.end(); ++it )
    {
        // window = *(it)

    }
}


but are there any others ways, ways that make it more readable?
using the iterators:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# include <iostream>
# include <vector>
# include <iomanip>

int main()
{
   std::vector<double> mainVec{1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0};
   std::vector<std::vector<double>> subVecs{};

   auto itr = mainVec.cbegin();

   while (itr != mainVec.cend() - 1)
   {
       subVecs.emplace_back(std::vector<double>{itr, itr+2});
       ++itr;
   }
   for (const auto& elemOuter : subVecs)
   {
       std::cout << std::fixed;
       for (const auto& elemInner : elemOuter)
       {
           std::cout << std::setprecision(2) << elemInner << " ";
       }
       std::cout << "\n";
   }
}
> I am basically trying to implement a sliding window function for a vector.

There is no need to copy elements of the vector (or to create sub-vectors) to have a sliding window into a vector.

If the elements of the vector need not be modified via the view through the sliding window, we can use std::string_view<int> (C++17) to represent a window into the vector.
http://en.cppreference.com/w/cpp/string/basic_string_view

If the elements of the vector must be modified through the sliding window, or in pre-C++17, we can roll out a windowed view of our own.

For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <vector>
#include <numeric>

template < typename T > struct sliding_window
{
    using iterator = typename std::vector<T>::iterator ;
    iterator first ;
    iterator last ;
    iterator vec_end ;

    std::size_t size() const { return last - first ; }
    iterator begin() { return first ; }
    iterator end() { return last ; }
    // etc.

    T& operator[] ( std::size_t pos ) { return first[pos] ; }
    // etc.

    sliding_window( std::vector<T>& vec, std::size_t sz )
        : first( vec.begin() ), last( vec.begin() + sz ), vec_end( vec.end() )
    { /* assert( vec.size() >= sz ) ; */ }

    bool slide( std::size_t by = 1 )
    {
        if( std::size_t(vec_end-last) < by ) return false ;

        first += by ;
        last += by ;
        return true ;
    }

    // etc.
};

int main()
{
    std::vector<int> vec(40) ;
    std::iota( std::begin(vec), std::end(vec), 10 ) ;

    sliding_window<int> window( vec, 20 ) ;
    do
    {
        for( int v : window ) std::cout << v << ' ' ;
        std::cout << '\n' ;
    } while( window.slide() ) ;
}

http://coliru.stacked-crooked.com/a/4508c58dc9cabb1a
The values actually don't have to be modified, but some data is has to be generated from it... So a basic_string_view could be a possible solution..
how are exactly proposing the basic_string_view to be used?
Something like this (compile with -std=c++17):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <vector>
#include <string_view>

template < typename T > using sliding_window = std::basic_string_view<T> ;

template < typename T >
sliding_window<T> make_window( const std::vector<T>& vec, std::size_t n, std::size_t offset = 0 )
{
    if( vec.size() < (offset+n) ) throw std::out_of_range( "the view is out of bounds\n" ) ;
    return { std::addressof( vec.front() ) + offset, n } ;
}

template < typename T > // unchecked slide
sliding_window<T>& slide( sliding_window<T>& sw, std::ptrdiff_t by = 1 )
{ return sw = { sw.begin()+by, sw.size() } ;  }

template < typename T > // checked slide
sliding_window<T>& slide( const std::vector<T>& vec, sliding_window<T>& sw, std::ptrdiff_t by = 1 )
{
    const auto offset = sw.begin() - std::addressof( vec.front() ) + by ;
    if( offset < 0  || vec.size() < ( offset + sw.size() ) )
        throw std::out_of_range( "out of bounds slide\n" ) ;

    return sw = { sw.begin()+by, sw.size() } ;
}

http://coliru.stacked-crooked.com/a/76c4896c8892d0e1
what do you mean by checked and unchecked slide?
Topic archived. No new replies allowed.