2017-02-03 9 views
0

C++でnタプルのリストを作成する方法は?私は数字の配列、その配列の要素のすべての可能なN個のタプル与え、生成したい:C++でのnタプルのリスト

Mathematicaではこれを用いて行われる:例えば

Tuples[{0, 1, 2}, 3] 

生成:

0,0,0 
0,0,1 
0,0,2 
0,1,0 
0,1,1 
0,1,2 
0,2,0 
0,2,1 
0,2,2 
1,0,0 
... 
2,2,2 
Pythonで

は、しかし、私はCA

list(product(range(0, 2), repeat=3)) 

How to create N-tuples in Python?を参照)を介して行われますC + +でそれを行う方法を把握していません。私は配列[0,1、...、num]を持ち、割り当てられた長さのnタプルを生成したいと思います。

おそらく、C++ではおそらくstd :: next_permutationやネストされたものを使用できますか?

+0

あなたが本当にタプルを必要はありますか?あなたのために働く2次元ベクトルのように見えます。 – NathanOliver

+0

考えてみてください。再帰関数を使って自分で書くことができますか? – supinf

+0

2次元ベクトルは完璧です!しかし、私の質問は、おそらく最も効率的な方法で上記のシーケンスを生成する方法についてです。再帰関数はまさに私がやりたいことです...しかし、私はそれを行う方法を見つけることができません – Galuoises

答えて

1

数字のベクトルが一意であると仮定します。

タプルが数字を増分するようにどのように表示されるかに気づいていますか?私たちはその事実を利用してこれを行うことができます。

最初に、タプル要素を引き出すセットが、基本的に「数字システム」の「数字」を形成していることに気づくでしょう。そこで、我々はdigits^tupleSizeタプルを持つことを知っています。

次に、カウンタを増分してカウンタから「数字」を取り除きます。

#include <cstddef> 
#include <cstdint> 
#include <vector> 

// Not strictly necessary. You can find other ways to end the loop 
uint32_t ipow(uint32_t base, uint32_t exp) 
{ 
    uint32_t result = 1; 
    while (exp) 
    { 
     if (exp & 1) 
      result *= base; 
     exp >>= 1; 
     base *= base; 
    } 

    return result; 
} 

std::vector<std::vector<uint32_t>> tuples(const std::vector<uint32_t> &set, uint32_t tupleSize) 
{ 
    std::vector<std::vector<uint32_t>> result; 

    uint32_t maxValue = ipow(set.size(), tupleSize); 

    for (uint32_t counter = 0; counter < maxValue; counter++) { 
     std::vector<uint32_t> tuple(tupleSize); 

     uint32_t currentValue = counter; 
     for (size_t i = 0; i < tupleSize; i++) { 
      uint32_t digit = currentValue % set.size(); 
      tuple[tupleSize - i - 1] = set[digit]; 
      currentValue /= set.size(); 
     } 

     result.push_back(tuple); 
    } 

    return result; 
} 

Demo

+0

ありがとう!それは完全に動作します! – Galuoises

関連する問題