6

これらの for ループがあります。

// output all possible combinations
for ( int i1 = 0; i1 <= 2; i1++ )
     {
         for ( int i2 = 0; i2 <= 2; i2++ )
             {
                 for ( int i3 = 0; i3 <= 2; i3++ )
                     {
                         for ( int i4 = 0; i4 <= 2; i4++ )
                             {
                                 for ( int i5 = 0; i5 <= 2; i5++ )
                                     {
                                         for ( int i6 = 0; i6 <= 2; i6++ )
                                             {
                                                 for ( int i7 = 0; i7 <= 2; i7++ )
                                                     {
                                                         //output created words to outFile
                                                         outFile
                                                         << phoneLetters[n[0]][i1]<< phoneLetters[n[1]][i2]
                                                         << phoneLetters[n[2]][i3]<< phoneLetters[n[3]][i4]
                                                         << phoneLetters[n[4]][i5]<< phoneLetters[n[5]][i6]
                                                         << phoneLetters[n[6]][i7]
                                                         << " ";

                                                         if ( ++count % 9 == 0 ) // form rows
                                                             outFile << std::endl;
                                                         }
                                                 }
                                         }
                                 }
                         }
                 }
         }

ひどいように見えますが、私はあまりにも初心者なので、それらを凝縮することに関してどこから始めればよいかわかりません.

このコードをもう少しきれいにできるように、誰かが私にポインタを1つか2つ教えてもらえますか?

4

4 に答える 4

8

7 つのレベルで 0、1、および 2 にインデックスを付けています。これはあまり効率的ではないかもしれませんが、これはどうですか:

int i1, i2, i3, i4, i5, i6, i7;
int j;

for (int i = 0; i < 2187; i++)
{
    // 0 through 2186 represent all of the ternary numbers from
    //    0000000 (base 3) to 2222222 (base 3).  The following
    //    pulls out the ternary digits and places them into i1
    //    through i7.

    j = i;

    i1 = j / 729;
    j = j - (i1 * 729);

    i2 = j / 243;
    j = j - (i2 * 243);

    i3 = j / 81;
    j = j - (i3 * 81);

    i4 = j / 27;
    j = j - (i4 * 27);

    i5 = j / 9;
    j = j - (i5 * 9);

    i6 = j / 3;
    j = j - (i6 * 3);

    i7 = j;

    // print your stuff
}

または、コメントの user315052 の提案に基づいて:

int d[7];

for (int i = 0; i < 2187; i++)
{
    int num = i;
    for (int j = 6; j >= 0; j--)
    {
        d[j] = num % 3;
        num = num / 3;
    }

    // print your stuff using d[0] ... d[6]]
} 
于 2012-07-31T20:07:48.807 に答える
3

一般的なケースでは、再帰を使用できます。

template <typename Stream, typename Iterator>
void generateNumbers(Stream& stream, Iterator begin, Iterator end) {
  if (end - begin == 7) {
    for (Iterator p = begin; p < end; p++) {
      stream << phoneLetters[n[*p]][*p];
    }
    stream << " ";
  } else {
    for (*end = 0; *end <= 2; ++*end)
      generateNumbers(stream,begin,end+1);
    if (end - begin == 6)
      stream << std::endl;
  }
}

バッファ ベクトルまたは単純な古い C 配列 (両方とも十分なサイズ) を使用して呼び出すことができます。

例えば:

std::vector<int> buf(7,0);
generateNumbers(std::cout,buf.begin(),buf.begin());
// or
int buf2[7];
generateNumbers(std::cout,buf2,buf2);

ただし、値がバイナリの場合は、PBrandoの答えの方が優れています。

于 2012-07-31T20:02:18.260 に答える
2

James McNellis がこの解決策について既にコメントしているようですが、以下に示します。

void phone_combo(int n[], int i[], int d, ostream &ofile, int &count) {
    if (d == 7) {
        //output created words to outFile
        ofile
        << phoneLetters[n[0]][i[0]]<< phoneLetters[n[1]][i[1]]
        << phoneLetters[n[2]][i[2]]<< phoneLetters[n[3]][i[3]]
        << phoneLetters[n[4]][i[4]]<< phoneLetters[n[5]][i[5]]
        << phoneLetters[n[6]][i[6]]
        << " ";
        if ( ++count % 9 == 0 ) // form rows
            ofile << std::endl;
        }
        return;
    }
    for (i[d] = 0; i[d] <= 2; i[d]++) {
        phone_combo(n, i, d+1, ofile, count);
    }
}

int i[7];
phone_combo(n, i, 0, outFile, count);
于 2012-07-31T20:10:50.710 に答える
0

これを単一の for ループに減らした応答が以前に投稿されましたが、何らかの理由で削除されました。

for( int i(0); i!= 2187; ++i )
{
    outFile
    << phoneLetters[n[0]][(i >> 6) & 0x01]<< phoneLetters[n[1]][(i >> 5) & 0x01]
    << phoneLetters[n[2]][(i >> 4) & 0x01]<< phoneLetters[n[3]][(i >> 3) & 0x01]
    << phoneLetters[n[4]][(i >> 2) & 0x01]<< phoneLetters[n[5]][(i >> 1) & 0x01]
    << phoneLetters[n[6]][i & 0x01]
    << ' ';

    if ( ++count % 9 == 0 ) // form rows
        outFile << '\n';
}

これは、可能な各順列を計算するために必要な正確な反復回数がわかっている場合にのみ機能します。

于 2012-08-01T04:26:26.567 に答える