2014-07-16 138 views
0

是否有一種巧妙的方式來遍歷一個n元組,其中元組中的每個元素都可以取k個值(總共有k個n個可能性)。我猜測k = 2,你可以通過十進制遞增來遍歷一個位數組。對於k的其他值呢?遍歷一個n元組

我實際上在k可以取{-1,0,1}的情況下,特別在C++中尋找可能的方法。

+3

你基本上只是問,直到它循環回到零遞增座K的n位數,對不對? –

+0

@KerrekSB:差不多。他沒有指定順序,所以我猜他不在乎。 –

回答

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

live example

+0

你提供的鏈接有編譯錯誤... –

+0

@BryanChen雅,編輯它,忘了保存。代碼可能需要適當地工作來處理具有任意整數類型的屬性(如枚舉),但骨頭在那裏。 – Yakk