CodeGym /Các khóa học /JAVA 25 SELF /Vòng lặp lồng nhau và cách áp dụng

Vòng lặp lồng nhau và cách áp dụng

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. Giới thiệu

Bắt đầu với câu hỏi: vì sao lại cần lồng một vòng lặp vào bên trong vòng lặp khác? Thực tế là dữ liệu hoặc bài toán của chúng ta thường không chỉ đi theo một hàng, mà có thể ở dạng bảng, lưới hoặc thậm chí cấu trúc đa chiều. Giả sử bạn muốn in ra màn hình bảng cửu chương, duyệt một mảng hai chiều hoặc tính số giao nhau giữa mọi cặp phần tử. Khi đó một vòng lặp là không đủ — cần vòng lặp trong vòng lặp.

Trong lập trình, vòng lặp lồng nhau giống như hai chiếc đồng hồ báo thức: vòng ngoài bắt đầu reo, và bên trong nó khởi chạy thêm một cái nữa, cái sẽ reo lặp đi lặp lại miễn là cái thứ nhất còn hoạt động. Nghĩa là, trong khi diễn ra một lần lặp “bên ngoài”, vòng trong đi hết toàn bộ hành trình của nó (và lặp lại điều đó cho mỗi lần lặp của vòng ngoài).

Ví dụ điển hình — giờ và phút. Giờ là vòng lặp ngoài từ 0 đến 23, phút là vòng lặp trong từ 0 đến 59. Mỗi lần vòng ngoài thay đổi, vòng trong kịp chạy qua tất cả giá trị của nó.

2. Cú pháp vòng lặp lồng nhau

Trong Java, cú pháp của vòng lặp lồng nhau không khác gì vòng lặp thông thường — bạn chỉ cần viết một vòng lặp bên trong thân của vòng lặp khác. Hãy xem ví dụ với forwhile:

// Vòng lặp for bên ngoài
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 4; j++)  // Vòng lặp for bên trong
    {
        System.out.print(i + "," + j + " ");
    }
    System.out.println(); // Xuống dòng sau vòng lặp bên trong
}

Ở đây, vòng lặp ngoài điều khiển biến i (từ 0 đến 2), còn vòng lặp trong điều khiển biến j (từ 0 đến 3). Với mỗi giá trị của i, vòng lặp trong sẽ chạy trọn vẹn từ j == 0 đến j == 3. Nếu chạy đoạn mã này, bạn sẽ thấy một bảng tọa độ gọn gàng:

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

Ví dụ tương tự với while:

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

Lưu ý: trong mỗi lần lặp của vòng ngoài, biến của vòng lặp trong (j) phải được khởi tạo lại, nếu không chúng ta sẽ chỉ thấy một dòng duy nhất!

3. Ví dụ về hoạt động của vòng lặp lồng nhau

Ví dụ 1: in bàn cờ (8x8)

Bài toán đầu tiên — in ra màn hình một bàn cờ cổ điển với các ô đen và trắng (giả sử ‘#’ là đen, ‘.’ là trắng). Thực hiện bằng vòng lặp lồng nhau for:

for (int row = 0; row < 8; row++)
{
    for (int col = 0; col < 8; col++)
    {
        // Nếu tổng chỉ số hàng và cột là chẵn — ô màu trắng, ngược lại là ô màu đen
        if ((row + col) % 2 == 0)
            System.out.print("_");
        else
            System.out.print("#");
    }
    System.out.println(); // Sau mỗi hàng thì xuống dòng
}

Kết quả:

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

Điểm quan trọng: việc lồng nhau đảm bảo rằng với mỗi hàng (row) chúng ta đi hết tất cả các cột (col). Nếu không lồng nhau, ta sẽ không có cấu trúc bàn cờ — chỉ được một hàng hoặc một cột.

Ví dụ 2: bảng cửu chương

Một ứng viên kinh điển cho vòng lặp lồng nhau! Hãy in bảng cửu chương 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();
}

Việc định dạng i * j + "\t" thêm khoảng đệm để bảng trông gọn gàng.

Kết quả:

  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. Vòng lặp lồng nhau và cách điều khiển — những điểm cần lưu ý

Ảnh hưởng của breakcontinue trong các vòng lặp lồng nhau

Đây là chỗ nhiều người mới dễ mắc! Nếu bạn dùng break hoặc continue trong vòng lặp bên trong, chúng chỉ tác động lên vòng lặp đó. Vòng ngoài vẫn tiếp tục chạy như bình thường.

Ví dụ: thoát sớm chỉ khỏi vòng lặp bên trong

for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 5; j++)
    {
        if (j == 3)
            break; // thoát chỉ khỏi vòng lặp bên trong!
        System.out.print(i + "," + j + " ");
    }
    System.out.println();
}

Kết quả:

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

Nếu bạn cần thoát ngay khỏi cả hai vòng lặp lồng nhau (ví dụ, dừng tìm kiếm ngay khi có kết quả khớp đầu tiên trong bảng), thường người ta dùng cờ (flag) hoặc một thủ thuật khác (chẳng hạn return — nếu mọi thứ diễn ra trong một hàm).

5. Trực quan hóa vòng lặp lồng nhau

Đôi khi khó “nhìn thấy” trình tự thực thi của các vòng lặp lồng nhau. Hãy xem sơ đồ khối sau:

sơ đồ vòng lặp lồng nhau

Dưới dạng bảng — tổng cộng sẽ có bao nhiêu lần lặp khi i từ 1 đến 3, j từ 1 đến 4?

i j (duyệt cho mỗi i) Số vòng lặp của vòng trong
1 1, 2, 3, 4 4
2 1, 2, 3, 4 4
3 1, 2, 3, 4 4
Tổng: 3 × 4 = 12

6. Lỗi và cạm bẫy khi làm việc với vòng lặp lồng nhau

Một lỗi phổ biến — khởi tạo sai biến của vòng lặp bên trong. Ví dụ, khai báo nó bên ngoài vòng lặp ngoài nhưng lại không đặt lại ở mỗi bước. Kết quả là vòng lặp trong có thể không chạy hoặc chạy sai.

int j = 0;
for (int i = 0; i < 3; i++)
{
    while (j < 4) // Ôi! j có thể đã bằng 4 sau vòng lặp đầu tiên.
    {
        System.out.print(i + "," + j + " ");
        j++;
    }
    System.out.println();
}

Ở đây, vòng lặp sẽ chỉ chạy đúng một lần. Đừng quên khởi tạo các biến của vòng lặp trong bên trong vòng lặp ngoài!

Ngoài ra, nếu vô tình viết hai vòng lặp lồng nhau với cùng một biến (for (int i = 0; ...) { for (int i = 0; ...) { ... } }), trình biên dịch sẽ cảnh báo bạn: biến đã được định nghĩa rồi.

1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Vòng lặp
Vòng lặp while, for, do-while
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION