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 57 58 59 60 61
|
#include <iostream>
#include <vector>
#include <cassert>
void add_tuples( const std::vector< std::vector<int> >& vectors, std::size_t pos,
std::vector<int> prefix, std::vector< std::vector<int> >& result )
{
if( pos == vectors.size() ) result.push_back(prefix) ;
else if( vectors[pos].empty() ) add_tuples( vectors, pos+1, prefix, result ) ; // note: skip empty vectors
else
{
for( int v : vectors[pos] )
{
prefix.push_back(v) ;
add_tuples( vectors, pos+1, prefix, result ) ;
prefix.pop_back() ;
}
}
}
std::vector< std::vector<int> > make_tuples( const std::vector< std::vector<int> >& vectors )
{
std::vector< std::vector<int> > result ;
add_tuples( vectors, 0, {}, result ) ;
return result ;
}
int main()
{
const std::vector< std::vector<int> > vectors = { {1,2,3}, {1,2,3}, {}, {1,2,3,4,5}, {}, {1,2}, {1,2,3} } ;
const auto tuples = make_tuples(vectors) ;
std::size_t ntups = 0 ;
for( const auto& tup : tuples )
{
std::cout << ++ntups << ". [ " ;
for( int v : tup ) std::cout << v << ' ' ;
std::cout << "]\n" ;
}
/////////////////////////////////////////////////////////////////////////////////
////////////////////////// sanity checks ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
std::size_t num_empty_vecs = 0 ;
std::size_t expected_ntups = 1 ;
for( const auto& vec : vectors )
{
if( !vec.empty() ) expected_ntups *= vec.size() ;
else ++num_empty_vecs ;
}
assert( num_empty_vecs < vectors.size() && ntups == expected_ntups ) ;
std::cout << "\n------------\n\n"
<< "#vectors: " << vectors.size() << '\n'
<< " #empty: " << num_empty_vecs << '\n'
<< "tup size: " << vectors.size() - num_empty_vecs << '\n'
<< " #tuples: " << ntups << '\n' ;
}
|