Skip to content

P06: Vòng lặp — Cơ bản

Tác giả: Hà Trí Kiên
Chủ đề: for, while, range(), break, continue, else trong loop


1. Tổng quan

Vòng lặp cho phép lặp lại một đoạn code nhiều lần. Đây là linh hồn của lập trình — hầu hết bài toán đều cần vòng lặp.

flowchart TD
    Start["Bắt đầu"] --> Check{"Còn lặp?"}
    Check -->|Yes| Body["Thân vòng lặp"]
    Body --> Check
    Check -->|No| End["Kết thúc"]

2. Vòng lặp for — Duyệt qua dãy

2.1. Cú pháp cơ bản

# Duyệt qua list
arr = [10, 20, 30, 40, 50]
for x in arr:
    print(x)
# Kết quả:
# 10
# 20
# 30
# 40
# 50

# Duyệt qua chuỗi
for c in "Hello":
    print(c)
# Kết quả:
# H
# e
# l
# l
# o

2.2. Hàm range() — Quan trọng!

flowchart LR
    A["range(stop)"] --> B["0, 1, 2, ..., stop-1"]
    C["range(start, stop)"] --> D["start, start+1, ..., stop-1"]
    E["range(start, stop, step)"] --> F["start, start+step, ..., < stop"]
# range(stop): từ 0 đến stop-1
for i in range(5):
    print(i, end=" ")  # 0 1 2 3 4

# range(start, stop): từ start đến stop-1
for i in range(1, 6):
    print(i, end=" ")  # 1 2 3 4 5

# range(start, stop, step): bước nhảy step
for i in range(0, 10, 2):
    print(i, end=" ")  # 0 2 4 6 8

# Đếm ngược
for i in range(10, 0, -1):
    print(i, end=" ")  # 10 9 8 7 6 5 4 3 2 1

# Đếm ngược với step
for i in range(10, 0, -2):
    print(i, end=" ")  # 10 8 6 4 2

2.3. Các cách dùng range() thường gặp

# Duyệt từ 0 đến n-1 (phổ biến nhất)
for i in range(n):
    ...

# Duyệt từ 1 đến n
for i in range(1, n + 1):
    ...

# Duyệt từ 0 đến n (bao gồm n)
for i in range(n + 1):
    ...

# Duyệt ngược từ n-1 về 0
for i in range(n - 1, -1, -1):
    ...

# Duyệt ngược từ n về 1
for i in range(n, 0, -1):
    ...

Tư duy: range(n) hay range(1, n+1)?

  • Dùng range(n) khi index từ 0 (truy cập mảng)
  • Dùng range(1, n+1) khi đếm từ 1 (in ra kết quả)

3. Vòng lặp while — Lặp khi còn điều kiện

3.1. Cú pháp cơ bản

1
2
3
4
5
# while: lặp khi điều kiện còn đúng
n = 5
while n > 0:
    print(n, end=" ")  # 5 4 3 2 1
    n -= 1

3.2. while True — Lặp vô hạn

1
2
3
4
5
6
# while True + break: lặp cho đến khi gặp break
while True:
    s = input()
    if s == "quit":
        break
    print(f"Ban vua nhap: {s}")

Cẩn thận vòng lặp vô hạn

1
2
3
4
5
# SAI: Quên cập nhật biến đếm → vòng lặp vô hạn
n = 5
while n > 0:
    print(n)  # In 5 mãi mãi!
    # Quên: n -= 1

3.3. while vs for

for while
Biết trước số lần lặp Không biết trước số lần lặp
Duyệt qua dãy Lặp khi còn điều kiện
for i in range(n): while n > 0:
# Dùng for khi biết số lần lặp
for i in range(10):
    print(i)

# Dùng while khi không biết số lần lặp
n = int(input())
while n != 1:
    if n % 2 == 0:
        n //= 2
    else:
        n = 3 * n + 1
    print(n, end=" ")

4. break — Thoát vòng lặp

1
2
3
4
5
# break: thoát ngay lập tức khỏi vòng lặp
for i in range(10):
    if i == 5:
        break  # Thoát khi i = 5
    print(i, end=" ")  # 0 1 2 3 4
flowchart TD
    Start["i = 0"] --> Check{"i < 10?"}
    Check -->|Yes| Body{"i == 5?"}
    Body -->|Yes| Break["break → Thoát"]
    Body -->|No| Print["print(i)"]
    Print --> Inc["i += 1"]
    Inc --> Check
    Check -->|No| End["Kết thúc"]

Ứng dụng: Tìm kiếm

arr = [3, 7, 2, 9, 5]
target = 9

found = False
for i, x in enumerate(arr):
    if x == target:
        print(f"Tim thay tai vi tri {i}")
        found = True
        break

if not found:
    print("Khong tim thay")

5. continue — Bỏ qua iteration hiện tại

1
2
3
4
5
# continue: bỏ qua phần còn lại của vòng lặp, quay lại đầu
for i in range(10):
    if i % 2 == 0:
        continue  # Bỏ qua số chẵn
    print(i, end=" ")  # 1 3 5 7 9
flowchart TD
    Start["i = 0"] --> Check{"i < 10?"}
    Check -->|Yes| Body{"i % 2 == 0?"}
    Body -->|Yes| Continue["continue → Quay lại đầu"]
    Body -->|No| Print["print(i)"]
    Print --> Inc["i += 1"]
    Continue --> Inc
    Inc --> Check
    Check -->|No| End["Kết thúc"]

break vs continue

# break: THOÁT vòng lặp
for i in range(10):
    if i == 5:
        break
    print(i, end=" ")  # 0 1 2 3 4

# continue: BỎ QUA iteration, tiếp tục lặp
for i in range(10):
    if i == 5:
        continue
    print(i, end=" ")  # 0 1 2 3 4 6 7 8 9

6. else trong loop — Chạy khi không break

# else: chạy khi vòng lặp kết thúc BÌNH THƯỜNG (không break)
for i in range(10):
    if i == 5:
        break
else:
    print("Khong break")  # Không in ra (vì đã break)

# else: chạy khi không break
for i in range(10):
    if i == 100:
        break
else:
    print("Khong break")  # In ra (vì không break)

Ứng dụng: Tìm kiếm với else

1
2
3
4
5
6
7
8
9
arr = [3, 7, 2, 9, 5]
target = 9

for i, x in enumerate(arr):
    if x == target:
        print(f"Tim thay tai vi tri {i}")
        break
else:
    print("Khong tim thay")

Tư duy: for-else

  • else chạy khi vòng lặp kết thúc bình thường (không break)
  • Hữu ích khi cần xác định "không tìm thấy" sau khi duyệt hết

7. Vòng lặp lồng nhau

1
2
3
4
5
6
7
8
9
# Lồng 2 vòng lặp
for i in range(3):
    for j in range(4):
        print(f"({i},{j})", end=" ")
    print()  # Xuống dòng sau mỗi hàng
# Kết quả:
# (0,0) (0,1) (0,2) (0,3)
# (1,0) (1,1) (1,2) (1,3)
# (2,0) (2,1) (2,2) (2,3)

Ứng dụng: In bảng cửu chương

1
2
3
4
for i in range(1, 10):
    for j in range(1, 10):
        print(f"{i*j:4}", end="")
    print()

Ứng dụng: Duyệt tất cả cặp (i, j)

1
2
3
4
5
n = 5
for i in range(n):
    for j in range(i + 1, n):  # j > i (tránh trùng)
        print(f"({i}, {j})", end=" ")
# Kết quả: (0,1) (0,2) (0,3) (0,4) (1,2) (1,3) (1,4) (2,3) (2,4) (3,4)

Độ phức tạp vòng lặp lồng

2 vòng lặp lồng nhau: O(n²) 3 vòng lặp lồng nhau: O(n³) → Cẩn thận khi n lớn!


8. enumerate() — Duyệt với index

arr = [10, 20, 30, 40, 50]

# Cách 1: Dùng index
for i in range(len(arr)):
    print(f"arr[{i}] = {arr[i]}")

# Cách 2: enumerate (ngắn hơn, rõ hơn)
for i, x in enumerate(arr):
    print(f"arr[{i}] = {x}")

# enumerate với start khác
for i, x in enumerate(arr, start=1):
    print(f"Phan tu thu {i}: {x}")

9. So sánh với C++

# for với range
for i in range(n):
    print(i)

# for với list
for x in arr:
    print(x)

# while
while n > 0:
    n -= 1
// for cổ điển
for (int i = 0; i < n; i++) {
    cout << i;
}

// range-based for (C++11)
for (int x : arr) {
    cout << x;
}

// while
while (n > 0) {
    n--;
}

10. Pattern thường gặp trong thi đấu

10.1. Đọc n phần tử

1
2
3
4
5
6
n = int(input())
arr = list(map(int, input().split()))
# Hoặc:
arr = []
for _ in range(n):
    arr.append(int(input()))

10.2. Duyệt mảng và xử lý

# Tìm max
max_val = arr[0]
for x in arr:
    if x > max_val:
        max_val = x

# Đếm phần tử thỏa mãn điều kiện
count = 0
for x in arr:
    if x > 0:
        count += 1

# Tính tổng
total = 0
for x in arr:
    total += x

10.3. Duyệt matrix

1
2
3
4
5
6
7
8
n, m = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(n)]

# Duyệt từng phần tử
for i in range(n):
    for j in range(m):
        print(matrix[i][j], end=" ")
    print()

10.4. Duyệt 4 hướng (đồ thị, BFS)

1
2
3
4
5
6
7
8
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]

for k in range(4):
    nx, ny = x + dx[k], y + dy[k]
    if 0 <= nx < n and 0 <= ny < m:
        # Xử lý ô (nx, ny)
        pass

10.5. Sinh tất cả hoán vị

def permutations(arr, l, r):
    if l == r:
        print(arr)
    else:
        for i in range(l, r + 1):
            arr[l], arr[i] = arr[i], arr[l]
            permutations(arr, l + 1, r)
            arr[l], arr[i] = arr[i], arr[l]  # Backtrack

permutations([1, 2, 3], 0, 2)

10.6. Duyệt đến khi gặp điều kiện dừng

1
2
3
4
5
6
7
n = int(input())
while n != 1:
    if n % 2 == 0:
        n //= 2
    else:
        n = 3 * n + 1
    print(n, end=" ")

11. Lưu ý / Cạm bẫy hay gặp

Bẫy 1: Vòng lặp vô hạn

1
2
3
4
5
6
7
8
9
# SAI: Quên cập nhật biến đếm
n = 10
while n > 0:
    print(n)  # In 10 mãi mãi!
    # Quên: n -= 1

# SAI: Điều kiện luôn đúng
while True:
    print("Loop")  # Không có break → vô hạn!

Bẫy 2: range() không bao gồm stop

1
2
3
4
5
6
7
# range(5) = 0, 1, 2, 3, 4 (KHÔNG có 5!)
for i in range(5):
    print(i)  # 0 1 2 3 4

# Nếu muốn bao gồm 5:
for i in range(6):  # 0 1 2 3 4 5
    print(i)

Bẫy 3: Chỉnh sửa list khi đang duyệt

# SAI: Xóa phần tử khi đang duyệt
arr = [1, 2, 3, 4, 5]
for x in arr:
    if x % 2 == 0:
        arr.remove(x)  # Có thể bỏ sót phần tử!

# ĐÚNG: Duyệt bản copy
arr = [1, 2, 3, 4, 5]
for x in arr[:]:  # arr[:] là bản copy
    if x % 2 == 0:
        arr.remove(x)

Bẫy 4: break chỉ thoát vòng lặp gần nhất

1
2
3
4
5
6
7
# break chỉ thoát vòng lặp TRONG CÙNG mà nó nằm trong
for i in range(3):
    for j in range(3):
        if j == 1:
            break  # Chỉ thoát vòng j, không thoát vòng i!
        print(f"({i},{j})", end=" ")
# Kết quả: (0,0) (1,0) (2,0)

Bẫy 5: for-else dễ hiểu nhầm

1
2
3
4
5
6
# else chạy khi KHÔNG break (không phải khi break!)
for i in range(10):
    if i == 5:
        break
else:
    print("Khong break")  # Không in ra (vì đã break)

12. Bài tập thực hành

Bài 1: In số từ 1 đến n

Đọc số nguyên n. In ra các số từ 1 đến n.

Lời giải
1
2
3
n = int(input())
for i in range(1, n + 1):
    print(i, end=" ")

Bài 2: Tính tổng 1 + 2 + ... + n

Đọc số nguyên n. Tính tổng S = 1 + 2 + ... + n.

Lời giải
1
2
3
4
5
6
7
n = int(input())
print(n * (n + 1) // 2)
# Hoặc:
# total = 0
# for i in range(1, n + 1):
#     total += i
# print(total)

Bài 3: In bảng cửu chương

In bảng cửu chương từ 1 đến 9.

Lời giải
1
2
3
4
for i in range(1, 10):
    for j in range(1, 10):
        print(f"{i*j:4}", end="")
    print()

Bài 4: Tìm số lớn nhất trong mảng

Đọc n số nguyên. Tìm số lớn nhất.

Lời giải
1
2
3
n = int(input())
arr = list(map(int, input().split()))
print(max(arr))

Bài 5: Collatz Conjecture

Cho số nguyên n. Nếu n chẵn, chia đôi. Nếu n lẻ, nhân 3 cộng 1. Lặp cho đến khi n = 1.

Lời giải
1
2
3
4
5
6
7
8
n = int(input())
while n != 1:
    print(n, end=" ")
    if n % 2 == 0:
        n //= 2
    else:
        n = 3 * n + 1
print(n)

13. Bài tập luyện tập

Bài 6: Đếm chữ số

Cho số nguyên dương n. Đếm n có bao nhiêu chữ số.

Lời giải
1
2
3
4
5
6
n = int(input())
count = 0
while n > 0:
    count += 1
    n //= 10
print(count)

Bài 7: Đảo ngược số

Cho số nguyên dương n. In ra số đảo ngược.

Lời giải
1
2
3
4
5
6
n = int(input())
result = 0
while n > 0:
    result = result * 10 + n % 10
    n //= 10
print(result)

Bài 8: Kiểm tra số hoàn hảo

Cho số nguyên dương n. Kiểm tra n có phải số hoàn hảo không (tổng các ước thực sự bằng chính nó).

Lời giải
1
2
3
4
5
6
7
8
9
n = int(input())
total = 0
for i in range(1, n):
    if n % i == 0:
        total += i
if total == n:
    print("So hoan hao")
else:
    print("Khong phai so hoan hao")

Bài 9: In tam giác số

Cho số nguyên dương n. In tam giác số như ví dụ.

Lời giải
1
2
3
4
5
n = int(input())
for i in range(1, n + 1):
    for j in range(1, i + 1):
        print(j, end=" ")
    print()

Bài 10: Tìm ước số

Cho số nguyên dương n. In ra tất cả các ước của n theo thứ tự tăng dần.

Lời giải
1
2
3
4
n = int(input())
for i in range(1, n + 1):
    if n % i == 0:
        print(i, end=" ")

Bài viết liên quan


Bài trước: P05: Câu lệnh điều kiện
Bài tiếp theo: P07: Vòng lặp — Nâng cao →


💬 Bình luận