是否有一种巧妙的方法来迭代n元组,其中元组中的每个元素都可以取k个值(总共k ^ n种可能性)。我猜测k = 2你可以通过递增十进制来迭代一个位数组。那个k的其他值怎么样?
在k可以取{-1,0,1}的情况下,我实际上是在C ++中专门寻找一种可能的方法。
答案 0 :(得分:0)
是
template<class E, E...es>
struct elements:std::integral_constant<unsigned, sizeof...(es)> { using type=E; };
template<class E, E e0, E e1, E... es>
constexpr E next_helper( elements<E, e0, e1, es...>, E e, E first ) {
return (e0 == e)?e1:next_helper( elements<E, e1, es...>{}, e, first );
}
template<class E, E e0>
constexpr E next_helper( elements<E, e0>, E e, E first ) {
return first;
}
template<class E, E e0, E... es>
constexpr E next_helper( elements<E, e0, es...>, E e ) {
return next_helper( elements<E, e0, es...>{}, e, e0 );
}
template<class elements, class E>
constexpr E next( E e ) {
return next_helper( elements{}, e );
}
template<class elements, class E>
constexpr E next( E e, unsigned N );
template<class E, E...es>
constexpr E next_helper( elements<E,es...>, E e, unsigned N ) {
return (N>=sizeof...(es))?next<elements>( e, (N%sizeof...(es)) ):next<elements>( next<elements>( e, (N)/2 ), (N+1)/2 );
}
template<class elements, class E>
constexpr E next( E e, unsigned N ) {
return (N==0)?e:(N==1)?next<elements>(e):next_helper<elements>( next_helper<elements>( N/2, e ), (N+1)/2 );
}
template<class E, E e0, E e1, E... es>
constexpr unsigned index_helper( elements<E, e0, e1, es...>, E e ) {
return (e0==e)?0:(index_helper( elements<E, e1, es...>{}, e )+1);
}
template<class E, E e0>
constexpr unsigned index_helper( elements<E, e0>, E e ) {
return 0;
}
template<class elements, class E>
constexpr unsigned index( E e ) {
return index_helper( elements{}, e );
}
template<class E, E e0, E... es>
constexpr unsigned first_helper(elements<E, e0, es...>) {
return e0;
}
template<class elements>
constexpr auto first() -> typename elements::type {
return first_helper(elements{});
}
template<class elements>
constexpr auto nth(unsigned n) -> typename elements::type {
return next<elements>( first<elements>(), n );
}
template<typename elements>
struct iteration_tuple {
using value_type = typename elements::type;
std::vector<value_type> data;
bool advance() {
bool finished = true;
for( value_type& e : data ) {
if ( first<elements>() != ( e = next<elements>(e) ) )
finished = false;
if (!finished)
break;
}
return finished;
}
iteration_tuple( unsigned size ) {
data.resize( size, first<elements>() );
}
};
int main() {
typedef elements<int, -1, 0, 1> sequence;
iteration_tuple<sequence> sample(3);
do {
for (int x:sample.data)
std::cout << x << ",";
std::cout << "\n";
} while(!sample.advance());
}