Wie kann man aus verschachtelten Schleifen ausbrechen?

Lesezeit: 5 Minuten

Benutzeravatar von user966379
Benutzer966379

Wenn ich eine verwende break Anweisung, es wird nur die innere Schleife brechen und ich muss ein Flag verwenden, um die äußere Schleife zu brechen. Aber wenn es viele verschachtelte Schleifen gibt, sieht der Code nicht gut aus.

Gibt es eine andere Möglichkeit, alle Schleifen zu brechen? (Bitte nicht verwenden 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

  • Sie können int i und int j versuchen, bevor die Schleife beginnt, und unter der Bedingung, dass sie 1001 sind, wird die Schleife die nächste nicht durchlaufen.

    – Khurram Ijaz

    14. März 2012 um 4:25 Uhr

  • C++-Version: stackoverflow.com/questions/1257744/…

    – Ciro Santilli OurBigBook.com

    19. März 2015 um 10:12 Uhr

  • Ich hatte einen Professor, dessen Lieblingsärger war, dass man keinen Parameter an Break senden konnte, um anzugeben, wie viele Level man hinausgehen konnte. Wenn es nach ihm ginge, wäre die Antwort auf Ihre Frage einfach “break(2);”, wobei “2” die Anzahl der Schleifen ist, aus denen ausgebrochen werden soll.

    – Adam Wise

    1. Oktober 2021 um 14:06 Uhr

Benutzeravatar von Srikar Appalaraju
Srikar Appalaraju

Nein, verderben Sie sich nicht den Spaß mit a break. Dies ist die letzte verbleibende gültige Verwendung von goto 😉

Wenn dies nicht der Fall ist, können Sie Flags verwenden, um aus tief verschachtelten Schleifen auszubrechen.

Ein anderer Ansatz zum Ausbrechen aus einer verschachtelten Schleife besteht darin, beide Schleifen in eine separate Funktion auszugliedern und von dieser Funktion zurückzukehren, wenn Sie sie verlassen möchten.

Zusammengefasst – um aus verschachtelten Schleifen auszubrechen:

  1. verwenden goto
  2. Flaggen verwenden
  3. Ausgliedern von Schleifen in separate Funktionsaufrufe

Konnte nicht widerstehen, xkcd hier einzufügen 🙂

Geben Sie hier die Bildbeschreibung ein

Quelle

Gotos gelten als schädlich aber wie viele Leute in den Kommentaren vermuten lassen, muss es nicht sein. Wenn es vernünftig eingesetzt wird, kann es ein großartiges Werkzeug sein. Alles, was in Maßen verwendet wird, macht Spaß.

  • Goto ist ungefähr so ​​​​klar, wie Sie hier bekommen, ja. Das Festlegen der Exit-Variablen auf 1000 ist noch klobiger.

    – Korrenos

    14. März 2012 um 4:33 Uhr

  • Ich möchte hinzufügen, dass Gotos nicht explizit böse sind, sie können nur für böse Zwecke verwendet werden. Ich finde, dass es einige Fälle gibt, zum Beispiel diesen, wo sie die beste Lösung sind. „Benutze keine Gotos“ ist ein guter Anfang, aber ich denke, der nächste Schritt in der Fähigkeit erlaubt dir „Benutze keine Gotos mit großer Reichweite“.

    – Atch

    14. März 2012 um 4:37 Uhr

  • obwohl ich mag gotoFür den WTF-Wert empfehle ich dringend, Route 3 zu wählen – wenn Sie ihn in allen außer den trivialsten Fällen anwenden, liefert er meiner Meinung nach auf lange Sicht die besten Ergebnisse.

    Benutzer719662

    7. Juni 2016 um 21:29 Uhr

  • Ich liebe diesen Comic. Als Randnotiz, goto ist am besten, wenn Sie wissen, was Sie tun und wie Sie es richtig verwenden. Ich benutze es die ganze Zeit, um aus verschachtelten Schleifen auszubrechen. Das Setzen eines Flags nur für diesen Zweck ist hässlich und fügt jeder Schleife eine zusätzliche Vergleichsanweisung hinzu. Das Erstellen einer Funktion führt zu exponentiellen Additionen/Subtraktionen des Stapelzeigers.

    – Roshub

    2. Dezember 2016 um 5:44 Uhr

  • +1. Und Donald E. Knuths Structured Programming with go to Statements (wiki.c2.com/?StructuredProgrammingWithGoToStatements) ist ein interessanter Artikel, um Dijkstra auszugleichen.

    – kmkaplan

    9. März 2018 um 9:21 Uhr

Verwenden:

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

  • Funktioniert, aber hässlich und nicht allgemein. Was ist, wenn jemand das Limit auf 2000 ändert (angenommen, der Code ist länger, sodass Sie ihn nicht sofort bemerken)?

    – ugoren

    14. März 2012 um 8:17 Uhr

  • @ugoren Dann ist es auch so einfach. Was wäre, wenn Sie a verwenden würden? const int count =1000 , in der globalen Initialisierung. oder als #define Makro.

    – Laksith

    19. Oktober 2015 um 7:37 Uhr


  • Wie @ugoren betont, ist dies keine allgemeine Lösung. Da dies der erste Google-Treffer für diese Frage ist, wäre es schön, wenn die allgemeine Lösung ausgewählt worden wäre. Nun, die Leute sind sowieso daran gewöhnt, sich die Nummer 2 anzusehen.

    – BeeOnRope

    4. November 2016 um 23:30 Uhr

  • Ich denke, ich brauche nur i = 1000?

    – Peter Wu

    2. August 2019 um 2:05 Uhr

Tungs Benutzeravatar
Tung

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

  • Die Lösung erhöht weiterhin beide Variablen um eins Unterbrechung was Ärger machen kann

    – TheSola10

    30. März 2017 um 7:33 Uhr

  • Man kann “stop = true;” setzen. und dann “break;”. Führen Sie dann direkt nach dem Ende der inneren “for”-Schleife “if (stop) break;” aus.

    – Jeff Grigg

    29. August 2017 um 5:49 Uhr

  • Ich denke, das ist die eleganteste Nicht-goto Lösung. Es erfordert nicht, die Grenzen zu kennen i und j innerhalb der Bedingung. Ich mag die Idee des Puttens if (stop) break; nach der inneren Schleife, die sich selbst könnte break nach Einstellung stop.

    – Willis Blackburn

    15. Oktober 2020 um 13:55 Uhr

Eine Möglichkeit besteht darin, alle verschachtelten Schleifen in eine Funktion zu stecken und von der innersten Schleife zurückzukehren, falls alle Schleifen ausgebrochen werden müssen.

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

Sie benötigen eine boolesche Variable, wenn Sie möchten, dass sie lesbar ist:

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

Wenn Sie möchten, dass es weniger lesbar ist, können Sie sich der booleschen Auswertung anschließen:

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

Als ultimative Möglichkeit können Sie die anfängliche Schleife ungültig machen:

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

  • Die letzte Lösung ist die beste für die Leistung. Überprüfen Sie keine weiteren booleschen Werte, wenn weitere bedingte Verzweigungen vermieden werden können.

    – Techniker

    8. Mai um 22:47 Uhr

Benutzeravatar von EvilTeach
Böses Lehren

Ich finde goto wird das Problem lösen

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

end:
stmt2 

 

  • Die letzte Lösung ist die beste für die Leistung. Überprüfen Sie keine weiteren booleschen Werte, wenn weitere bedingte Verzweigungen vermieden werden können.

    – Techniker

    8. Mai um 22:47 Uhr

Benutzeravatar von R Sahu
R Sahu

Nutzen Sie diesen weisen Rat des LLVM-Teams:

“Verwandeln Sie Prädikatschleifen in Prädikatfunktionen”

Sehen:

http://llvm.org/docs/CodingStandards.html#turn-predicate-loops-into-predicate-functions

1423090cookie-checkWie kann man aus verschachtelten Schleifen ausbrechen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy