JavaRush /Курси /JAVA 25 SELF /Вкладені цикли та їхнє застосування

Вкладені цикли та їхнє застосування

JAVA 25 SELF
Рівень 4 , Лекція 5
Відкрита

1. Вступ

Почнімо із запитання: навіщо взагалі вкладати один цикл у інший? Річ у тім, що часто наші дані чи завдання структуровані не просто в один ряд, а, наприклад, у таблицю, сітку або навіть у багатовимірну структуру. Припустімо, ви хочете вивести на екран таблицю множення, перебрати двовимірний масив або пройти всі пари елементів. Тут одного циклу явно не вистачить — потрібен цикл у циклі.

У програмуванні вкладений цикл — це як два будильники: зовнішній починає «дзвонити», а всередині нього запускається ще один, який працюватиме щоразу, поки перший активний. Тож поки триває одна «зовнішня» ітерація, внутрішня проходить увесь свій цикл (і робить це знову й знову для кожної ітерації зовнішнього циклу).

Гарний приклад — години та хвилини. Години — це зовнішній цикл від 0 до 23, хвилини — внутрішній цикл від 0 до 59. На кожну зміну зовнішнього циклу внутрішній встигає пройти всі свої значення.

2. Синтаксис вкладених циклів

У Java синтаксис вкладених циклів нічим не відрізняється від звичайних — ви просто пишете один цикл всередині тіла іншого. Розгляньмо приклади з for і while:

// Зовнішній цикл for
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 4; j++)  // Внутрішній цикл for
    {
        System.out.print(i + "," + j + " ");
    }
    System.out.println(); // Після внутрішнього циклу — перехід на новий рядок
}

Тут зовнішній цикл контролює змінну i (від 0 до 2), а внутрішній — змінну j (від 0 до 3). Для кожного значення i внутрішній цикл повністю проходить від j == 0 до j == 3. Якщо виконаєте цей код, побачите охайну таблицю координат:

0,0 0,1 0,2 0,3 
1,0 1,1 1,2 1,3 
2,0 2,1 2,2 2,3 

Аналогічний приклад із використанням while:

int i = 0;
while (i < 3)
{
    int j = 0;
    while (j < 4)
    {
        System.out.print(i + "," + j + " ");
        j++;
    }
    System.out.println();
    i++;
}

Зверніть увагу: під час кожної ітерації зовнішнього циклу змінну внутрішнього циклу (j) потрібно ініціалізувати наново, інакше побачите лише один рядок!

3. Приклади роботи вкладених циклів

Приклад 1: виведення шахівниці (8×8)

Нехай перше завдання — вивести на екран класичну шахівницю у вигляді чорних і білих клітинок (позначимо: «#» — чорна, «_» — біла). Реалізуємо це за допомогою вкладених циклів for:

for (int row = 0; row < 8; row++)
{
    for (int col = 0; col < 8; col++)
    {
        // Якщо сума індексів рядка та стовпця парна — клітинка біла, інакше чорна
        if ((row + col) % 2 == 0)
            System.out.print("_");
        else
            System.out.print("#");
    }
    System.out.println(); // Після кожного рядка — перехід на новий рядок
}

Результат:

_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_

Важливий момент: вкладеність гарантує, що для кожного рядка (row) ми повністю проходимо всі стовпці (col). Без вкладеності ми б не отримали структуру шахівниці — лише один рядок або один стовпець.

Приклад 2: таблиця множення

Один із класичних прикладів для вкладених циклів. Виведімо таблицю множення 1–9:

for (int i = 1; i <= 9; i++)
{
    for (int j = 1; j <= 9; j++)
    {
        System.out.print(i * j + "\t");
    }
    System.out.println();
}

Форматування i * j + "\t" додає символ табуляції, щоб таблиця виглядала охайно.

Результат:

  1   2   3   4   5   6   7   8   9 
  2   4   6   8  10  12  14  16  18 
  3   6   9  12  15  18  21  24  27 
  4   8  12  16  20  24  28  32  36 
...
  9  18  27  36  45  54  63  72  81 

4. Вкладені цикли й керування ними — нюанси

Про вплив break і continue у вкладених циклах

Саме тут багато новачків роблять помилку. Якщо ви використовуєте break або continue у внутрішньому циклі, вони впливають лише на цей цикл. Зовнішній цикл продовжує роботу без змін.

Приклад: достроковий вихід лише з внутрішнього циклу

for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 5; j++)
    {
        if (j == 3)
            break; // вихід лише з внутрішнього циклу
        System.out.print(i + "," + j + " ");
    }
    System.out.println();
}

Результат:

0,0 0,1 0,2 
1,0 1,1 1,2 
2,0 2,1 2,2 

Якщо треба вийти одразу з двох вкладених циклів (наприклад, терміново завершити пошук при першому успішному збігу в таблиці), зазвичай використовують прапорець або спеціальний прийом (наприклад, return — якщо все відбувається всередині методу).

5. Візуалізація вкладених циклів

Іноді буває складно «побачити» послідовність виконання вкладених циклів. Розгляньмо таку блок‑схему:

схема вкладених циклів

У табличній формі: скільки загалом ітерацій буде виконано за i від 1 до 3, j від 1 до 4?

i j (перебирається для кожного i) Ітерацій внутрішнього циклу
1 1, 2, 3, 4 4
2 1, 2, 3, 4 4
3 1, 2, 3, 4 4
Усього: 3 × 4 = 12

6. Помилки й підводні камені під час роботи з вкладеними циклами

Поширена помилка — некоректна ініціалізація змінної внутрішнього циклу. Наприклад, оголосити її поза зовнішнім циклом і не скидати її щоразу. У результаті внутрішній цикл може взагалі не виконуватися або виконуватися неправильно.

int j = 0;
for (int i = 0; i < 3; i++)
{
    while (j < 4) // Увага: після першої ітерації j уже міг дорівнювати 4.
    {
        System.out.print(i + "," + j + " ");
        j++;
    }
    System.out.println();
}

Тут цикл виконається лише один раз. Не забувайте ініціалізувати змінні внутрішніх циклів всередині зовнішніх!

Якщо випадково написати два вкладені цикли з однаковими змінними (for (int i = 0; ...) { for (int i = 0; ...) { ... } }), компілятор повідомить про помилку: змінну вже оголошено.

1
Опитування
Цикли, рівень 4, лекція 5
Недоступний
Цикли
Цикли while, for, do-while
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ