迭代一个n元组

Iterating through an n-tuple

本文关键字:一个 元组 迭代      更新时间:2023-10-16

是否有一种聪明的方法来迭代n元组,其中元组中的每个元素都可以取k个值(总共k^n种可能性)。我猜当k=2时你可以通过十进制递增来遍历位数组。k的其他值呢?

我实际上是在c++中寻找一种可能的方法在这种情况下k可以取{-1,0,1}

可以。

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());
}

生活例子