Разкъсване на вложени цикли

1. Общ преглед

В този урок ще създадем няколко примера, за да покажем различни начини за използване на break в цикъл. След това ще видим и как да прекратим цикъл, без изобщо да използваме break .

2. Проблемът

Вложените цикли са много полезни, например, за търсене в списък със списъци.

Един пример би бил списък със студенти, където всеки студент има списък с планирани курсове. Да кажем, че искаме да намерим името на един човек, който е планирал курс 0 .

Първо, щракнахме върху списъка със студенти. След това, вътре в този цикъл, щракнахме върху списъка с планирани курсове.

Когато отпечатаме имената на студентите и курсовете, ще получим следния резултат:

student 0 course 0 course 1 student 1 course 0 course 1

Искахме да намерим първия студент, който планира курс 0 . Ако обаче просто използваме цикли, тогава приложението ще продължи да търси, след като курсът бъде намерен.

След като намерим човек, който е планирал конкретния курс, искаме да спрем да търсим. Продължаването на търсенето ще отнеме повече време и ресурси, докато не се нуждаем от допълнителна информация. Ето защо искаме да излезем от вложения цикъл.

3. Прекъсване

Първият вариант, който трябва да излезем от вложен цикъл, е просто да използваме оператора break :

String result = ""; for (int outerCounter = 0; outerCounter < 2; outerCounter++) { result += "outer" + outerCounter; for (int innerCounter = 0; innerCounter < 2; innerCounter++) { result += "inner" + innerCounter; if (innerCounter == 0) { break; } } } return result;

Имаме външен цикъл и вътрешен цикъл, и двата цикъла имат две итерации. Ако броячът на вътрешния цикъл е равен на 0, ние изпълняваме командата break . Когато стартираме примера, той ще покаже следния резултат:

outer0inner0outer1inner0

Или можем да коригираме кода, за да го направим малко по-четлив:

outer 0 inner 0 outer 1 inner 0

Това ли искаме?

Почти вътрешният цикъл се прекратява от инструкцията за прекъсване, след като е намерено 0. Външният цикъл обаче продължава, което не е това, което искаме. Искаме да спрем обработката напълно, веднага щом получим отговора.

4. Етикетиран Break

Предишният пример беше стъпка в правилната посока, но трябва малко да я подобрим. Можем да направим това, като използваме етикет за почивка :

String result = ""; myBreakLabel: for (int outerCounter = 0; outerCounter < 2; outerCounter++) { result += "outer" + outerCounter; for (int innerCounter = 0; innerCounter < 2; innerCounter++) { result += "inner" + innerCounter; if (innerCounter == 0) { break myBreakLabel; } } } return result;

А белязан почивка ще прекрати външния контур вместо само на вътрешния контур. Постигаме това, като добавяме myBreakLabel извън цикъла и променяме изявлението break, за да спре myBreakLabel . След като стартираме примера, получаваме следния резултат:

outer0inner0

Можем да го прочетем малко по-добре с някакво форматиране:

outer 0 inner 0

Ако погледнем резултата, можем да видим, че както вътрешният, така и външният цикъл са прекратени, което искахме да постигнем.

5. Връщане

Като алтернатива бихме могли да използваме и оператора return , за да върнем директно резултата, когато бъде намерен:

String result = ""; for (int outerCounter = 0; outerCounter < 2; outerCounter++) { result += "outer" + outerCounter; for (int innerCounter = 0; innerCounter < 2; innerCounter++) { result += "inner" + innerCounter; if (innerCounter == 0) { return result; } } } return "failed";

Етикетът се премахва и операторът break се заменя с оператор return .

Когато изпълним кода по-горе, получаваме същия резултат като за етикетираното прекъсване. Имайте предвид, че за да работи тази стратегия, обикновено трябва да преместим блока от цикли в собствен метод.

6. Заключение

И така, току-що разгледахме какво да правим, когато трябва да излезем по-рано от цикъл, като например, когато намерихме елемента, който търсим. На почивка Ключовата дума е полезно за единични вериги, както и ние можем да използваме етикетирани почивка и за вложени цикъла.

Като алтернатива можем да използваме оператор return . Използването на return прави кода по-четлив и по-малко податлив на грешки, тъй като не е нужно да мислим за разликата между немаркирани и етикетирани прекъсвания.

Чувствайте се свободни да разгледате кода на GitHub.