नेस्टेड छोरों से बाहर कैसे तोड़ें?


96

यदि मैं एक breakबयान का उपयोग करता हूं , तो यह केवल आंतरिक लूप को तोड़ देगा और बाहरी लूप को तोड़ने के लिए मुझे कुछ ध्वज का उपयोग करने की आवश्यकता है। लेकिन अगर कई नेस्टेड लूप हैं, तो कोड अच्छा नहीं लगेगा।

सभी छोरों को तोड़ने का कोई और तरीका है? (कृपया उपयोग न करें goto stmt।)

for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; j++) {
       if(condition) {
            // both of the loops need to break and control will go to stmt2
       }
   }

}

stmt2

2
आप लूप शुरू होने से पहले int i और int j ट्राई कर सकते हैं और फिर इस शर्त पर उन्हें 1001 कर देंगे कि लूप अगले को पुनरावृत्त नहीं करेगा।
खुर्रम एजाज

जवाबों:


43

उपयोग:

if (condition) {
    i = j = 1000;
    break;
}

49
काम करता है, लेकिन बदसूरत और सामान्य नहीं। क्या होगा अगर कोई 2000 की सीमा को बदल दे (मान लें कि कोड लंबा है, तो आप तुरंत इसे नोटिस नहीं करते हैं)?

1
@ यूगोरेन यह भी इतना सरल है। क्या होगा यदि आपने const int count =1000 वैश्विक प्रारंभ में एक का उपयोग किया है । या #defineमैक्रो के रूप में ।
Laksith

4
जैसा कि @ugoren बताते हैं, यह एक सामान्य समाधान नहीं है। चूंकि यह इस प्रश्न के लिए पहली Google हिट है, इसलिए अच्छा होगा यदि सामान्य समाधान का चयन किया गया हो। वैसे भी लोगों को # 2 बाहर की जाँच करने के लिए उपयोग किया जाता है।
BeeOnRope

1
मुझे लगता है कि मुझे केवल I = 1000 की आवश्यकता है?
पीटर वू

189

नहीं, एक के साथ मज़ा खराब मत करो break। यह अंतिम शेष वैध उपयोग है goto;)

यदि ऐसा नहीं है तो आप गहरे नेस्टेड छोरों को तोड़ने के लिए झंडे का उपयोग कर सकते हैं।

नेस्टेड लूप से बाहर निकलने का एक अन्य तरीका यह है कि दोनों छोरों को एक अलग फ़ंक्शन में फैक्टर करें, और जब आप बाहर निकलना चाहते हैं तो उस फ़ंक्शन से वापस लौटें।

संक्षेप में - नेस्टेड छोरों से बाहर निकलने के लिए:

  1. उपयोग goto
  2. झंडे का उपयोग करें
  3. फैक्टर आउट लूप्स को अलग-अलग फ़ंक्शन कॉल में

यहाँ xkcd सहित विरोध नहीं किया जा सका :)

यहां छवि विवरण दर्ज करें

स्रोत

गोटो को हानिकारक माना जाता है लेकिन टिप्पणियों में कई लोगों का सुझाव है कि इसकी आवश्यकता नहीं है। अगर विवेकपूर्ण तरीके से इस्तेमाल किया जाए तो यह एक बेहतरीन उपकरण हो सकता है। मॉडरेशन में उपयोग की जाने वाली कोई भी चीज़ मज़ेदार होती है।


29
गोटो के बारे में के रूप में स्पष्ट के रूप में आप यहाँ, हाँ मिल जाएगा। निकास चर को 1000 पर सेट करना और भी अधिक कठिन है।
कोरनोस

3
मैं जोड़ना चाहूंगा कि गोटो स्पष्ट रूप से बुराई नहीं हैं, उनका उपयोग केवल बुराई के लिए किया जा सकता है। मुझे लगता है कि ऐसे कुछ मामले हैं, उदाहरण के लिए, यह सबसे अच्छा समाधान है। "गोटो का उपयोग न करें" एक अच्छी शुरुआत है, लेकिन मुझे लगता है कि कौशल में अगला कदम आपको "लंबी दूरी के गोटो का उपयोग न करने" की अनुमति देता है।
Aatch

1
मैं इससे असहमत होना चाहता हूं: "फंक्शन पॉइंटर को जोड़ने / घटाने के घातीय मात्रा में एक फ़ंक्शन परिणाम"। यदि कोई स्थानीय (स्थिर) फ़ंक्शन होता है जिसे प्रोग्राम फ्लो में केवल एक बिंदु पर कहा जाता है, तो कोई भी आधा-सभ्य कंपाइलर इसे इनलाइन करेगा, और परिणामस्वरूप कोड मूल रूप से गोटो के समान है। यह संभवतः किसी भी संकलक के लिए सबसे आसान अनुकूलन का मामला है।
DrV

1
आम तौर पर Refactoring सबसे साफ समाधान है। हालाँकि, यदि किसी बाहरी लूप चर को आंतरिक लूप के दौरान बदल दिया जाता है, तो चीजें जटिल हो जाती हैं। एक संभावना यह है कि चर को संदर्भ (पॉइंटर) द्वारा आंतरिक फ़ंक्शन में पास किया जाए, लेकिन इससे कंपाइलर अनुकूलन को भ्रमित किया जा सकता है और अनावश्यक अतिरिक्त कोड का उत्पादन किया जा सकता है। एक अन्य संभावना मॉड्यूल स्तर पर ऐसे चर को स्थिर बनाने की है, लेकिन यह बहुत सुंदर नहीं है, या तो। सी दुर्भाग्य से नेस्टेड फ़ंक्शंस को याद कर रहा है, क्योंकि वे इस समस्या को हल करेंगे - जब तक कि आप जीसीसी का उपयोग करने के लिए खुद को बांधने के लिए तैयार न हों जो एक विस्तार प्रदान करता है।
DrV

1
+1। और डोनाल्ड ई। नथ का संरचित प्रोग्रामिंग टू स्टेट्स गो ( wiki.c2.com/?StructuredProgrammingWithGoToStatements ) एक दिलचस्प लेख है जो दिज्क्स्ट्रा को संतुलित करता है।
किमीकप्लान

40
bool stop = false;
for (int i = 0; (i < 1000) && !stop; i++)
{
    for (int j = 0; (j < 1000) && !stop; j++)
    {
        if (condition)
            stop = true;
    }
}

समाधान अभी भी ब्रेक पर एक-एक करके दोनों चर बढ़ाता है जो परेशानी का कारण बन सकता है
TheSola10

7
एक सेट "बंद करो = सच हो सकता है?" और फिर "ब्रेक;"। फिर, अंदर के अंत के ठीक बाद "लूप" के लिए, "अगर (रोक) ब्रेक;"।
जेफ ग्रिग

34

एक तरीका यह है कि सभी नेस्टेड लूप्स को एक फंक्शन में डाल दिया जाए और सभी छोरों को तोड़ने की आवश्यकता के सबसे आंतरिक लूप से वापस लौटें।

function() 
{    
  for(int i=0; i<1000; i++)
  {
   for(int j=0; j<1000;j++)
   {
      if (condition)
        return;
   }
  }    
}

1
मेरे लिए सबसे अच्छा समाधान लगता है
Luca Steeb

20

मुझे लगता है कि gotoसमस्या का समाधान होगा

for(int i = 0; i < 1000; i++) {
    for(int j = 0; j < 1000; i++) {
        if (condition) {
            goto end;
        }
    }
}

end:
stmt2 

@chikuba मैं से जवाब मिल गया cprogramming.com/tutorial/goto.html और अपने उत्तर पोस्ट नहीं कर रहा है जब मैं एक ही बात कर रहा हूँ thats क्यों मुझे नहीं आपकी पोस्ट दिखाई
रंजीत केएन

15

अगर आपको यह पढ़ने योग्य चाहिए तो आपको बूलियन चर की आवश्यकता होगी:

bool broke = false;
for(int i = 0; i < 1000; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      broke = true;
      break;
    }
  }
  if (broke)
    break;
}

यदि आप इसे कम पठनीय चाहते हैं तो आप बूलियन मूल्यांकन में शामिल हो सकते हैं:

bool broke = false;
for(int i = 0; i < 1000 && !broke; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      broke = true;
      break;
    }
  }
}

एक अंतिम तरीके के रूप में आप प्रारंभिक लूप को अमान्य कर सकते हैं:

for(int i = 0; i < size; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      i = size;
      break;
    }
  }
}


4

सावधानी: यह उत्तर वास्तव में अस्पष्ट निर्माण दर्शाता है।

यदि आप जीसीसी का उपयोग कर रहे हैं, तो इस लाइब्रेरी को देखें । PHP की तरह, breakनेस्टेड लूप की संख्या को स्वीकार कर सकते हैं जिसे आप बाहर निकलना चाहते हैं। आप कुछ इस तरह लिख सकते हैं:

for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; j++) {
       if(condition) {
            // break two nested enclosing loops
            break(2);
       }
   }
}

और हुड के तहत यह वास्तव में :) का उपयोग कर रहा हैgoto
जैकोबक

@ iX3 अगर मैं मदद करता है कि इनलाइन कोडांतरक और जेएमपी अनुदेश का उपयोग कर सकते हैं।
डेब्लर

@ डब्लर, मुझे नहीं पता था कि आप उस लाइब्रेरी के लेखक थे। मेरी टिप्पणी का मतलब प्रतिक्रिया के रूप में नहीं था, बल्कि यह मानते हुए कि यह पुस्तकालय स्वीकृत उत्तर के समान विधि का उपयोग करता है । उम्मीद है कि आपकी टिप्पणी एक मजाक के रूप में थी क्योंकि मुझे लगता है कि एक भाषा सुविधा (यहां gotoतक कि ) का उपयोग करना इनलाइन एएसएम (मशीन विशिष्ट, एक गलती करने में आसान, पढ़ने में कठिन, ...) के लिए काफी अधिक है।
जेकबॉक

3
for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; i++) {
       if(condition) {
            goto end;
   }
} 

end:

3

यदि आपको आई और जे के मूल्यों की आवश्यकता है, तो यह काम करना चाहिए लेकिन दूसरों की तुलना में कम प्रदर्शन के साथ

for(i;i< 1000; i++){    
    for(j; j< 1000; j++){
        if(condition)
            break;
    }
    if(condition) //the same condition
        break;
}

ध्यान दें कि यदि स्थिति निर्भर है, jतो स्थिति के मूल्य को अभी भी काम करने के लिए किसी तरह से संग्रहीत करने की आवश्यकता है।
SuperBiasedMan

1
आप सही हैं लेकिन ब्रेक के बाद , j का मान नहीं बदलता है और इसलिए शर्त का मूल्य है।
अली एरेन अलिक

यह एक टूटा हुआ समाधान है और सामान्य रूप से मान्य नहीं है। या तो जे अपने पाश के बाहर से परिभाषित नहीं है या for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; j++) { if (workComplete[i][j]) break; /* do work */ workComplete[i][j] = true; } if (workComplete[i][j]) break; ... }जा रहा है हमेशा भीतरी पाश की पहली यात्रा के बाद बाहरी पाश से बाहर तोड़।
चाई टी। रेक्स


-3
for(int i = 0; i < 1000; i++) {
    for(int j = 0; j < 1000; i++) {
       if(condition) {
          func(para1, para2...);
          return;
       }
    }
}

func(para1, para2...) {
    stmt2;
}

तो मूल रूप से आप कह रहे हैं कि यह (1) अतिरिक्त फ़ंक्शन कॉल का एक गुच्छा बनाना चाहिए और फिर (2) शेष समय के लिए स्पिन conditionहो जाता है जब वह गलत हो जाता है। ओह, और दूसरा लूप हमेशा के लिए चलेगा क्योंकि इसके iबदले में वृद्धि होती है j,
उफ़

-4
i = 0;

do
{
  for (int j = 0; j < 1000; j++) // by the way, your code uses i++ here!
  {
     if (condition)
     {
       break;
     }
  }

  ++i;

} while ((i < 1000) && !condition);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.