2012-07-31 11 views
6

मेरे पास इन्हें लूप के लिए है।सी ++ लूप के लिए नेस्टेड कंडेनसिंग

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

यह भयानक लग रहा है, लेकिन मुझे यह जानने के लिए एक बहुत नया काम है कि उन्हें कंडेनस करने के संबंध में कहां से शुरू किया जाए।

क्या कोई मुझे एक सूचक या दो दे सकता है ताकि मैं इस कोड को थोड़ा साफ कर सकूं?

+13

वाह ... यह कला का एक काम है ... – Mysticial

+0

मैं इसे फिर से लिखना चाहता हूं, इसलिए यह संभवतः – frankV

+3

के रूप में कुछ लूप का उपयोग करता है, यह एक रिकर्सिव फ़ंक्शन में कनवर्ट करने के लिए काफी छोटा होगा जहां प्रत्येक रिकर्सिव कॉल जमा होता है अगला मान, और जब आपके पास पर्याप्त मूल्य हों, तो आप संख्या मुद्रित करें। वैकल्पिक रूप से, एक चल रहे काउंटर को रखें, और इसे बेस 3 में परिवर्तित करें (या इसके आधार 3 घटकों की गणना करें)। –

उत्तर

6

आप सात स्तरों पर 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]] 
} 
+0

काफी साफ है। – Puppy

+3

मैं घटाव/गुणात्मक चीज के बजाय 'j% = X' का उपयोग करूंगा। यदि आप पहले 7 वें शब्द को पॉप्युलेट करना शुरू करते हैं, तो आप केवल 3 का उपयोग करके स्थिरांक को रद्द कर सकते हैं। यदि आप 'i' को सरणी में स्विच करते हैं, तो यह 3 से एक मोड के रूप में शब्दों की गणना करने के लिए एक साधारण सरल पाश बन जाता है, प्रत्येक पर 3 से div यात्रा। – jxh

+0

उपयोगकर्ता315052 के सुझाव को प्रतिबिंबित करने के लिए मेरा उत्तर संपादित किया गया। बहुत अच्छा विचार! – John

2

सामान्य स्थिति में, आप प्रत्यावर्तन इस्तेमाल कर सकते हैं:

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

कौन सा आप या तो एक बफर वेक्टर या एक सादे पुराने सी सरणी (दोनों के पास पर्याप्त आकार के साथ) का उपयोग कर कॉल कर सकते हैं।

उदाहरण के लिए:

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

लेकिन अगर अपने मूल्यों द्विआधारी कर रहे हैं, PBrando के जवाब बेहतर है।

2

मैं देख रहा हूँ जेम्स 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); 
0

पहले एक प्रतिक्रिया पोस्ट की गई थी जो इसे लूप के लिए एकल में कम कर देती थी लेकिन इसे किसी कारण से हटा दिया गया था।

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

यह केवल तभी काम करने जा रहा है यदि आप प्रत्येक संभावित क्रमपरिवर्तन की गणना करने के लिए आवश्यक पुनरावृत्तियों की सटीक संख्या को जानते हैं।

संबंधित मुद्दे