BÀI 4(JAVA): SỬ DỤNG CÁC CẤU TRÚC LẶP

4.1. Sử dụng vòng lặp while để lặp với điều kiện kiểm tra trước

4.1.1. Lý thuyết liên quan

  • Khái niệm: Vòng lặp while là cấu trúc lặp cơ bản nhất trong Java, liên tục thực thi khối lệnh bên trong thân khi biểu thức điều kiện trả về giá trị true. Biểu thức điều kiện được đánh giá ngay ở đầu vòng lặp; nếu điều kiện sai (false) ngay từ đầu thì thân vòng lặp sẽ không chạy lần nào.

  • Tác dụng: Để xử lý những bài toán lặp, mà số lần lặp chưa biết trước nhưng phụ thuộc vào sự biến đổi của trạng thái dữ liệu (như thuật toán tìm ước số chung, bài toán chia nguyên).

  • Ý nghĩa: Giúp kiểm soát điều kiện an toàn trước khi xử lý, tránh thực thi khối lệnh khi dữ liệu không thỏa mãn.

4.1.2. Trình tự thực hiện

B1: Khởi tạo biến điều khiển trước khi bước vào vòng lặp.

B2: Viết cấu trúc while (dieu_kien) kèm thân vòng lặp trong cặp ngoặc {}:

int n = 12345;
int tongChuSo = 0;
while (n > 0) {
    tongChuSo += (n % 10); // Lấy chữ số cuối cộng dồn
    n = n / 10;            // Bỏ chữ số cuối
}

B3: Luôn đảm bảo bên trong thân vòng lặp có câu lệnh làm thay đổi giá trị của biến điều khiển để hướng tới điều kiện dừng, tránh gây lặp vô hạn.

B4: Kiểm thử chương trình với các giá trị đầu vào đặc biệt (ví dụ: số 0 hoặc số âm).

Bài tập áp dụng

Bài tập 4.1.1: Đếm số chữ số của một số nguyên dương

Yêu cầu: Khai báo một số nguyên dương long n = 9876543210L;. Dùng vòng lặp while liên tục chia nguyên cho 10 để đếm xem số n có bao nhiêu chữ số. In kết quả đếm ra màn hình.

Bài tập 1.2: Tìm ước số chung lớn nhất (USCLN) bằng giải thuật Euclid

Yêu cầu: Cho hai số nguyên dương a = 48b = 18. Sử dụng vòng lặp while (b != 0) với thuật toán lấy dư r = a % b; a = b; b = r; để tìm và xuất ước chung lớn nhất của hai số ra màn hình.

4.2. Sử dụng vòng lặp do – while để kiểm tra điều kiện sau

4.2.1. Lý thuyết liên quan

  • Khái niệm: Vòng lặp do-while đánh giá biểu thức điều kiện ở cuối mỗi chu kỳ lặp. Do đó, thân vòng lặp luôn luôn được thực thi ít nhất một lần bất kể điều kiện ban đầu là đúng hay sai.

  • Tác dụng: Rất thích hợp để hiển thị bảng chọn (menu tương tác) hoặc ép buộc người dùng nhập dữ liệu đúng quy chuẩn từ bàn phím (nếu nhập sai thì bắt buộc nhập lại).

  • Ý nghĩa: Giảm thiểu mã nguồn trùng lặp khi cần xử lý hành động trước rồi mới kiểm tra kết quả. Cú pháp kết thúc bằng dấu chấm phẩy ; sau while(dieu_kien);.

4.2.2. Trình tự thực hiện:

  • B1: Mở khối lệnh bằng từ khóa do { ... }.

  • B2: Đặt các lệnh thực thi (nhập dữ liệu, hiển thị menu) vào bên trong thân vòng lặp.

  • B3: Viết điều kiện lặp lại sau từ khóa while kèm dấu chấm phẩy ; ở cuối:

    int tuoi;
    do {
        System.out.print("Nhập tuổi học sinh (từ 15 đến 30): ");
        tuoi = sc.nextInt();
    } while (tuoi < 15 || tuoi > 30); // Lặp lại nếu nhập sai
    
  • B4: Thực thi và thử nhập các giá trị sai để kiểm tra cơ chế lặp ép buộc.

Bài tập áp dụng

Bài tập 4.2.1: Nhập điểm số an toàn

Yêu cầu: Sử dụng Scanner và vòng lặp do-while để yêu cầu nhập điểm thực hành của học sinh. Điều kiện hợp lệ là điểm phải thuộc đoạn [0.0, 10.0]. Nếu nhập sai, xuất cảnh báo: “Điểm không hợp lệ, vui lòng nhập lại!” và tiếp tục lặp lại.

Bài tập 4.2.2: Menu xác nhận tiếp tục giao dịch

Yêu cầu: Viết chương trình mô phỏng một lần tính tiền. Sau khi tính xong, dùng do-while để hỏi: “Bạn có muốn tiếp tục giao dịch không? (Nhập 1 để tiếp tục, 0 để dừng): “. Vòng lặp sẽ tiếp tục chạy khi người dùng nhập 1 và chỉ dừng lại khi người dùng nhập 0.

4.3. Sử dụng vòng lặp for truyền thống và for-each nâng cao

4.3.1. Lý thuyết liên quan

  • Khái niệm:

    • Vòng lặp for gom cả 3 thành phần: khởi tạo biến đếm, kiểm tra điều kiệncập nhật bước nhảy vào cùng một dòng lệnh. Biến điều khiển khai báo trong for chỉ tồn tại trong phạm vi của vòng lặp đó.

    • Vòng lặp for-each (Enhanced for loop) được dùng để duyệt tuần tự từng phần tử trong một mảng từ đầu đến cuối một cách tự động mà không cần dùng biến chỉ số i.

  • Tác dụng: for thích hợp với các bài toán đã biết trước số bước lặp hoặc cần chỉ số i; for-each giúp mã nguồn ngắn gọn, trực quan và ngăn ngừa hoàn toàn lỗi tràn chỉ số mảng.

  • Ý nghĩa: Tối ưu cấu trúc mã nguồn, dễ đọc, dễ kiểm tra và vận hành an toàn trên các tập dữ liệu.

4.3.2. Trình tự thực hiện

TH1: Sử dụng for cơ bản để xử lý dãy số:

for (int i = 1; i <= n; i++) {
    tong += i;
}

TH2: Sử dụng for-each để duyệt xuất các phần tử của một mảng:

double[] mangLuong = {7.5, 8.0, 9.2, 6.8};
for (double luong : mangLuong) {
    System.out.println("Mức lương: " + luong);
}

Ghi nhớ nguyên tắc: Biến lặp trong for-each mang tính chất chỉ đọc (read-only), không thể thay đổi giá trị phần tử mảng gốc thông qua biến này.

Bài tập áp dụng

Bài tập 4.3.1: In dãy số Fibonacci

Yêu cầu: Dùng vòng lặp for in ra N số đầu tiên của dãy Fibonacci (f_0 = 0, f_1 = 1, f_n = f_{n-1} + f_{n-2}) với N = 12. Các số in trên cùng một hàng ngang cách nhau dấu cách.

Bài tập 3.2: Tính tổng và đếm mảng bằng for-each

Yêu cầu: Khởi tạo mảng số nguyên int[] arr = {15, 24, 33, 40, 55, 60, 72};. Dùng vòng lặp for-each để duyệt mảng, tính tổng các phần tử chia hết cho 5 và in ra tổng cùng số lượng phần tử tìm thấy.