1

配列を使用してすべての可能なシーケンスを出力する方法について、何らかのアイデアが必要です。例えば、

array 1: AA BB
array 2: CC
array 3: DD EE FF
array 4: GG

次に、次のように、配列ごとに 1 つのシーケンスのみを使用して、任意の配列から可能なすべての組み合わせをリストする必要があります。

AA CC DD GG
AA CC EE GG
AA CC FF GG
BB CC DD GG
BB CC EE GG
BB CC FF GG

誰かがこれを行う方法を知っているか、私を始めることができますか?

4

8 に答える 8

2

これらが 4 つの異なる配列である場合、配列の 1 つを反復する 4 つのネストされたサイクルを記述するより良いオプションは考えられません。すべての配列を保持する 2 次元配列がある場合は、再帰を使用することをお勧めします。

于 2013-03-12T07:16:22.240 に答える
2

sizeof() を使用した配列ごとの要素の量が不明であることを意味していると思います。他の人が述べたように、5 つの for ループをネストするだけです。

int main()
{
    //naming arrays a,b,c,d,e, change accordingly
    //this function prints the combinations of 1 char
    int aElements = sizeof(a) / sizeof(a[0]);
    int bElements = sizeof(b) / sizeof(b[0]);
    int cElements = sizeof(c) / sizeof(c[0]);
    int dElements = sizeof(d) / sizeof(d[0]);
    int eElements = sizeof(e) / sizeof(e[0]);
    for (int i = 0; i < aElements; i++){
        for (int j = 0; j < bElements; j++){
            for (int k = 0; k < cElements; k++){
                for (int l = 0; l < dElements; l++){
                    for (int m = 0; m < eElements; m++){
                        cout << a[i] << b[j] << c[k] << d[l] << e[m] << endl;
                    }
                }
            }
        }
    }
}

組み合わせの数を調べるには、内側のループにカウンターを配置するか、要素の数を組み合わせの数 (この場合は 1) で割り、それらすべてを乗算します。EG、あなたの例では、(4 / 1) * (2 / 1) * (2 / 1) * (6 / 1) * (2 / 1) = 192 の組み合わせになります。2 文字ごとに組み合わせを行う場合、2 番目の例では (4 / 2) * (2 / 2) * (2 / 2) * (6 / 2) * (2 / 2) = 6 つの組み合わせになります。次の関数は、2 の組み合わせを出力します。

int main()
    {
    //naming arrays a,b,c,d,e, change accordingly
    //this function prints the combinations of 2 chars
    int aElements = sizeof(a) / sizeof(a[0]);
    int bElements = sizeof(b) / sizeof(b[0]);
    int cElements = sizeof(c) / sizeof(c[0]);
    int dElements = sizeof(d) / sizeof(d[0]);
    int eElements = sizeof(e) / sizeof(e[0]);
    for (int i = 0; i < aElements - 1; i+=2){
        for (int j = 0; j < bElements - 1; j+=2){
            for (int k = 0; k < cElements - 1; k+=2){
                for (int l = 0; l < dElements - 1; l+=2){
                    for (int m = 0; m < eElements - 1; m+=2){
                        cout << a[i] << a[i+1] << b[j] << b[j+1] << c[k] << c[k+1]  << d[l] << d[l+1] << e[m] << e[m+1] << endl;
                        }
                    }
                }
            }
        }
}

2番目に行ったのは、カウンターを1ではなく2ずつ増やし、範囲外にならないように要素数から1を引き、1ではなく2つの連続する要素を出力することだけでした。これは、任意の数の文字の組み合わせで機能します。

于 2013-04-17T07:15:20.607 に答える
2

C++11 スタイル!

#include <iostream>
#include <vector>
#include <utility>
#include <iterator>

// metaprogramming boilerplate:

template<typename... L>
struct first_type {};
template<typename T, typename... L>
struct first_type<T, L...> {
  typedef T type;
};
template<typename... L>
using FirstType = typename first_type<L...>::type;

namespace aux {
    using std::begin;
    template<typename C>
    auto adl_begin( C&&c )->decltype( begin(std::forward<C>(c)) );
    template<typename C>
    auto adl_cbegin( C const&c )->decltype( begin(c) );
}
template<typename Container>
struct iterator_type {
  typedef decltype( aux::adl_begin(std::declval<Container>()) ) iterator;
  typedef decltype( aux::adl_cbegin(std::declval<Container>()) ) const_iterator;
};
template<typename Container>
using IteratorType = typename iterator_type<Container>::iterator;

template<typename Container>
struct value_type {
  typedef typename std::iterator_traits< IteratorType<Container> >::value_type type;
};
template<typename Container>
using ValueType = typename value_type<Container>::type;

// Actual problem specific code:
template<typename Func, typename T>
void ForEachPossibility_Helper( Func&& f, std::vector<T>& result) {
  f(result);
}

template<typename Func, typename T, typename Container, typename... Containers>
void ForEachPossibility_Helper( Func&& f, std::vector<T>& result, Container&& arr0, Containers&&... arrays) {
  for( auto const& str:arr0 ) {
    result.push_back(str);
    ForEachPossibility_Helper( std::forward<Func>(f), result, std::forward<Containers>(arrays)... );
    result.pop_back();
  }
}

template<typename Func, typename... Containers>
void ForEachPossibility( Func&& f, Containers&&... arrays) {
    typedef ValueType<FirstType<Containers...>> T;
    std::vector<T> result;
    ForEachPossibility_Helper( std::forward<Func>(f), result, std::forward<Containers>(arrays)... );
}

const char* arr1[] = {"AA", "BB"};
const char* arr2[] = {"CC"};
const char* arr3[] = {"DD", "EE", "FF"};
const char* arr4[] = {"GG"};

int main() {
  ForEachPossibility( []( std::vector<const char*> const& result ){
    for( auto&& str:result ) {
      std::cout << str;
    }
    std::cout << "\n";
  }, arr1, arr2, arr3, arr4 );
}

for ループは 2 つしかなく、そのうちの 1 つは印刷用であることに注意してください。

于 2013-04-17T19:14:43.990 に答える
1

可変数の配列がある場合、Tocsの答えは正しいです。常に 4 つの配列がある場合は、単純に 4 つのネストされたループを使用できます。

   for (unsigned int i1 = 0; i1 < a1.size(); ++i1)
        for (unsigned int i2 = 0; i2 < a2.size(); ++i2)
            for (unsigned int i3 = 0; i3 < a3.size(); ++i3)
                for (unsigned int i4 = 0; i4 < a4.size(); ++i4)
                    cout << a1[i1] << " " << a2[i2] << " " << a3[i3] << " " << a4[i4] << std::endl;

完全なコードについては、 http://ideone.com/YcW84Qを参照してください。

于 2013-04-17T07:14:01.950 に答える
1

更新のために編集

各インデックスを 1 つずつ更新する代わりに、組み合わせを反復して更新する必要があります...

参照: n 枚のトランプの可能なすべての組み合わせを反復処理するにはどうすればよいですか?

だから今はこんな感じ

#include <iostream>
#include <vector>
#include <string>
using namespace std;

bool UpdateCombination (std::vector<int> &comboindices, int count, int n)
{
    for (int i = 1; i <= n; ++i)
    {
        if (comboindices[n - i] < count - i)
        {
            ++comboindices[n - i];
            for (int j = n - i + 1; j < n; ++j)
            {
                comboindices[j] = comboindices[j-1] + 1;
            }
            return false;
        }
    }
    return true;
}

void ResetCombination (std::vector<int> &comboindices, int n)
{
    comboindices.resize(n);
    for (int i = 0; i < n; ++i)
    {
        comboindices[i] = i;
    }
}

void PrintArrays (const std::vector<std::vector<std::string>> items, int count)
{
    std::vector<std::vector<int>> indices;
    int n = items.size();
    indices.resize(items.size());

    for(auto i = indices.begin (); i != indices.end (); ++i)
    {
        ResetCombination((*i),count);
    }

    while (true) //Iterate until we've used all of the last array of items
    {
            for (int i = 0; i < n; ++i)
            {
                cout << "{";
                for (auto j = indices[i].begin (); j != indices[i].end (); ++j)
                {
                    int ji = (*j);
                    cout << (items[i])[ji] << " ";
                }
                cout << "} ";

            }
            cout << endl;

            //Update to the next indice
            for (int i = n - 1; i >= 0; --i)
            {
                    bool done = UpdateCombination (indices[i],items[i].size(),count);
                    if (!done)
                    {
                            break;
                    }
                    else if (done && i == 0)
                    {
                        return; //Escape.
                    }
                    else
                    {
                        ResetCombination(indices[i],count);
                    }
            }
    }

}
 //{A,B,C,D},{A,B},{A,B},{A,B,C,D,E,F},{A,B}


int main() {

    vector<vector<string>> lists;
    lists.resize(5);
    lists[0].push_back("A");
    lists[0].push_back("B");
    lists[0].push_back("C");
    lists[0].push_back("D");

    lists[1].push_back("A");
    lists[1].push_back("B");

    lists[2].push_back("A");
    lists[2].push_back("B");

    lists[3].push_back("A");
    lists[3].push_back("B");
    lists[3].push_back("C");
    lists[3].push_back("D");
    lists[3].push_back("E");
    lists[3].push_back("F");

    lists[4].push_back("A");
    lists[4].push_back("B");



    PrintArrays(lists,2);

    int pause;
    cin >> pause;
    return 0;
}

私たちに与える...

{A B } {A B } {A B } {A B } {A B } 
{A B } {A B } {A B } {A C } {A B } 
{A B } {A B } {A B } {A D } {A B } 
{A B } {A B } {A B } {A E } {A B } 
{A B } {A B } {A B } {A F } {A B } 
{A B } {A B } {A B } {B C } {A B } 
{A B } {A B } {A B } {B D } {A B } 
{A B } {A B } {A B } {B E } {A B } 
{A B } {A B } {A B } {B F } {A B } 
{A B } {A B } {A B } {C D } {A B } 
{A B } {A B } {A B } {C E } {A B } 
{A B } {A B } {A B } {C F } {A B } 
{A B } {A B } {A B } {D E } {A B } 
{A B } {A B } {A B } {D F } {A B } 
{A B } {A B } {A B } {E F } {A B } 
{A C } {A B } {A B } {A B } {A B } 
{A C } {A B } {A B } {A C } {A B } 
{A C } {A B } {A B } {A D } {A B } 
{A C } {A B } {A B } {A E } {A B } 
{A C } {A B } {A B } {A F } {A B } 
{A C } {A B } {A B } {B C } {A B } 
{A C } {A B } {A B } {B D } {A B } 
{A C } {A B } {A B } {B E } {A B } 
{A C } {A B } {A B } {B F } {A B } 
{A C } {A B } {A B } {C D } {A B } 
{A C } {A B } {A B } {C E } {A B } 
{A C } {A B } {A B } {C F } {A B } 
{A C } {A B } {A B } {D E } {A B } 
{A C } {A B } {A B } {D F } {A B } 
{A C } {A B } {A B } {E F } {A B } 
{A D } {A B } {A B } {A B } {A B } 
{A D } {A B } {A B } {A C } {A B } 
{A D } {A B } {A B } {A D } {A B } 
{A D } {A B } {A B } {A E } {A B } 
{A D } {A B } {A B } {A F } {A B } 
{A D } {A B } {A B } {B C } {A B } 
{A D } {A B } {A B } {B D } {A B } 
{A D } {A B } {A B } {B E } {A B } 
{A D } {A B } {A B } {B F } {A B } 
{A D } {A B } {A B } {C D } {A B } 
{A D } {A B } {A B } {C E } {A B } 
{A D } {A B } {A B } {C F } {A B } 
{A D } {A B } {A B } {D E } {A B } 
{A D } {A B } {A B } {D F } {A B } 
{A D } {A B } {A B } {E F } {A B } 
{B C } {A B } {A B } {A B } {A B } 
{B C } {A B } {A B } {A C } {A B } 
{B C } {A B } {A B } {A D } {A B } 
{B C } {A B } {A B } {A E } {A B } 
{B C } {A B } {A B } {A F } {A B } 
{B C } {A B } {A B } {B C } {A B } 
{B C } {A B } {A B } {B D } {A B } 
{B C } {A B } {A B } {B E } {A B } 
{B C } {A B } {A B } {B F } {A B } 
{B C } {A B } {A B } {C D } {A B } 
{B C } {A B } {A B } {C E } {A B } 
{B C } {A B } {A B } {C F } {A B } 
{B C } {A B } {A B } {D E } {A B } 
{B C } {A B } {A B } {D F } {A B } 
{B C } {A B } {A B } {E F } {A B } 
{B D } {A B } {A B } {A B } {A B } 
{B D } {A B } {A B } {A C } {A B } 
{B D } {A B } {A B } {A D } {A B } 
{B D } {A B } {A B } {A E } {A B } 
{B D } {A B } {A B } {A F } {A B } 
{B D } {A B } {A B } {B C } {A B } 
{B D } {A B } {A B } {B D } {A B } 
{B D } {A B } {A B } {B E } {A B } 
{B D } {A B } {A B } {B F } {A B } 
{B D } {A B } {A B } {C D } {A B } 
{B D } {A B } {A B } {C E } {A B } 
{B D } {A B } {A B } {C F } {A B } 
{B D } {A B } {A B } {D E } {A B } 
{B D } {A B } {A B } {D F } {A B } 
{B D } {A B } {A B } {E F } {A B } 
{C D } {A B } {A B } {A B } {A B } 
{C D } {A B } {A B } {A C } {A B } 
{C D } {A B } {A B } {A D } {A B } 
{C D } {A B } {A B } {A E } {A B } 
{C D } {A B } {A B } {A F } {A B } 
{C D } {A B } {A B } {B C } {A B } 
{C D } {A B } {A B } {B D } {A B } 
{C D } {A B } {A B } {B E } {A B } 
{C D } {A B } {A B } {B F } {A B } 
{C D } {A B } {A B } {C D } {A B } 
{C D } {A B } {A B } {C E } {A B } 
{C D } {A B } {A B } {C F } {A B } 
{C D } {A B } {A B } {D E } {A B } 
{C D } {A B } {A B } {D F } {A B } 
{C D } {A B } {A B } {E F } {A B }

出力を確認します。 http://ideone.com/L5AZVv

古い ideone リンク: http://ideone.com/58ARAZ

于 2013-03-12T14:54:00.453 に答える
1

私が見る限り、シーケンスを取得する配列の順序を気にする必要はありません。この場合、再帰は確かに役に立ちます。どういうわけかそのように見えます:

void printSequences(ListOfYourArrays list, int index) {
    if (list.size() > index) {
        array a = list.getElementAt(index);
        //Make a cycle that reads items from your array one by one
        while (...)
            System.out.print(item);
        //And now you need to print all combinations for the rest of arrays in you list
        printSequences(list, index + 1);
    } else
        System.out.println();
}

必要なのは、配列をリストに追加して関数を呼び出すことだけです

printSequences(list, 0);
于 2013-03-12T07:30:34.927 に答える
0

4ループはNpow(4)につながります。

4つの配列を2つに分割します。

for each(arr 1){
  for each(arr 2)
  insert into container 1.
}


for each(arr 3){
  for each(arr 4)
  insert into container 2.
}


for each(container 1){
  for each(container 2)
  insert into container3 (*iter 1 + *iter 2)
}

したがって、複雑さは最大3NPow(2)になり、N pow(4)よりも小さくなります。

于 2013-03-12T13:04:37.697 に答える
0

もう1つの可能性は、現在の組み合わせを「カウント」することです(たとえば、バイナリをカウントする場合など)。(0,0,0,0)から始めて、最大配列インデックス(1,0,2,0)まで数えます。各ステップで、最初のインデックスに1を追加することから始めます。最大インデックス(ここでは1)より大きい場合は、ゼロに設定して次のインデックスに進みます

結果:

(0,0,0,0)-> AA CC DD GG

(1,0,0,0)-> BB CC DD GG

(0,0,1,0)-> AA CC EE GG

(1,0,1,0)-> BB CC EE GG

(0,0,2,0)-> AA CC FF GG

(1,0,2,0)-> BB CC FF GG

于 2013-03-12T09:15:14.530 に答える