C ++ Condensation nested for loops

I have this for loops.

// 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; } } } } } } } 

It looks terrible, but I'm too much new to know where to start to thicken them.

Can someone give me a pointer or two so that I can make this code a bit neat?

+6
source share
4 answers

You index 0, 1, and 2 on seven levels. This may not be very effective, but what about this:

 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 } 

Or, based on the user's suggestion315052 in the comments:

 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]] } 
+6
source

In general, you can use recursion:

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

What you can call using either a buffer vector or a plain old C array (both of sufficient size).

For instance:

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

But if your values ​​are binary, it is better to answer PBrando .

+2
source

I see that James McNellis has already commented on this decision, but here he is:

 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); 
+2
source

There was an answer earlier that reduced this to one loop, but was deleted for some reason.

 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'; } 

This will work if you know the exact number of iterations needed to compute each possible permutation.

0
source

Source: https://habr.com/ru/post/921799/


All Articles