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 48 49 50 51 52 53 54 55 56
|
#include <iostream>
#include <utility>
#include <random>
#include <iterator>
#include <list>
#include <string>
namespace matlab
{
// return the one based matlab index of value in range; return 0 if value is not present
// note that one based index is unusual (and somewhat inconvenient) in C++
template < typename RANGE, typename T >
std::size_t find( const RANGE& range, const T& value )
{
std::size_t index = 1 ; // one based index (starts at one)
for( const auto& item : range )
{
if( value == item ) return index ; // found it; return the index
++index ; // increment the index before moving to the next item
}
return 0 ; // value was not found
}
// choose a random item from a non-empty range and return a pair of values
// pair{ the chosen item, its one based matlab index }
template < typename ITERATOR > auto select_from( ITERATOR begin, ITERATOR end )
{
static std::mt19937 rng( std::random_device{}() ) ;
std::size_t n = std::distance( begin, end ) ; // number of items
std::size_t index = std::uniform_int_distribution<std::size_t>( 1, n )(rng); // one based random index
return std::make_pair( *std::next( begin, index-1 ), index ) ; // return item at that index and the index
}
// choose a random item from a non-empty range and return a pair of values
// pair{ the chosen item, its one based matlab index }
template < typename RANGE > auto select_from( const RANGE& range )
{ return select_from( std::begin(range), std::end(range) ) ; }
}
int main()
{
const int state[] = { 11, 37, 88, 9 } ;
const int current_state = 37 ;
const auto current_state_index = matlab::find( state, current_state ) ;
std::cout << current_state_index << '\n' ; // 2
const std::list<std::string> number_strings { "one", "two", "three", "four", "five", "six", "seven" } ;
std::cout << matlab::find( number_strings, "five" ) << '\n' ; // 5
auto[ ival, index_ival ] = matlab::select_from(state) ;
std::cout << "from array state: randomly selected " << ival << " with index " << index_ival << '\n' ;
auto[ strval, index_strval ] = matlab::select_from(number_strings) ;
std::cout << "from list number_strings: randomly selected \"" << strval << "\" with index " << index_strval << '\n' ;
}
|