Smart way to split a vector into smaller overlapping vectors?
Nov 18, 2017 at 11:40pm UTC
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?
Nov 19, 2017 at 6:09am UTC
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" ;
}
}
Nov 19, 2017 at 7:00am UTC
> 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
Nov 19, 2017 at 10:31am UTC
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..
Nov 19, 2017 at 12:13pm UTC
how are exactly proposing the basic_string_view to be used?
Nov 19, 2017 at 1:15pm UTC
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
Nov 19, 2017 at 7:44pm UTC
what do you mean by checked and unchecked slide?
Topic archived. No new replies allowed.