Bài tập mảng bổ trợ (10 bài)

BÀI TẬP MẢNG BỔ TRỢ — GIẢI CHI TIẾT (Java_Lab_Basic_Ex.pdf)

Bộ 10 bài nhỏ trong tệp PDF 1 trang (bản gốc là ảnh). Mỗi bài đi theo cấu trúc rút gọn: đề → phân tích → code → chạy → kiểm thử → lỗi → câu hỏi, vì đây là bài luyện phản xạ, không phải bài thiết kế lớp.

# Bài Kỹ thuật
1 Nhập tên, in lại Scanner.nextLine
2 Số 1–7 → thứ switch
3 Phương thức bình phương của 10 static method
4 10 bội số đầu của 5 for
5 10 số nguyên tố đầu while + hàm nguyên tố
6 Chẵn / lẻ if + %
7 Nguyên âm switch/equalsIgnoreCase
8 Đếm cặp bằng nhau liền kề duyệt i và i+1
9 Phần tử không nhỏ hơn mọi số trước max tiền tố
10 Ma trận chỉ gồm 0/1 mảng 2 chiều

Bài 1 — Nhập tên và in lại

Đề: Write a program to accept a name and display the same.

Phân tích: dùng nextLine() để nhận cả chuỗi có dấu cách. Cảnh báo: nếu trước đó có nextInt() thì phải ăn Enter (buổi 2).

// ===== NhapTen.java =====
import java.util.Scanner;

public class NhapTen {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Nhap ten: ");
        String ten = sc.nextLine();
        System.out.println("Xin chao " + ten);
        sc.close();
    }
}

Chạy:

Nhap ten: Nguyen Van An
Xin chao Nguyen Van An

Kiểm thử: tên rỗng → Xin chao (hợp lệ); tên 1 từ → đúng. Lỗi: dùng next() → chỉ nhận Nguyen; quên import → cannot find symbol. Câu hỏi: khi nào nextLine trả về chuỗi rỗng? (Ngay sau nextInt.)


Bài 2 — Số 1–7 → thứ trong tuần

Đề: accept a number between 1 and 7 and return the corresponding day of the week.

Phân tích: so bằng với danh sách rời rạc → switch; ngoài miền → default.

// ===== ThuTrongTuan.java =====
import java.util.Scanner;

public class ThuTrongTuan {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Nhap so (1-7): ");
        int n = sc.nextInt();

        switch (n) {
            case 1: System.out.println("Monday");    break;
            case 2: System.out.println("Tuesday");   break;
            case 3: System.out.println("Wednesday"); break;
            case 4: System.out.println("Thursday");  break;
            case 5: System.out.println("Friday");    break;
            case 6: System.out.println("Saturday");  break;
            case 7: System.out.println("Sunday");    break;
            default: System.out.println("Khong hop le");
        }
        sc.close();
    }
}

Bảng kiểm thử: 1 → Monday; 7 → Sunday; 0 → Không hợp lệ; 8 → Không hợp lệ. Lỗi: thiếu break → in nhiều thứ liền nhau. Câu hỏi: vì sao default phải đặt cuối nhưng không cần break? (Nó là nhánh cuối, không rơi xuống đâu nữa.)


Bài 3 — Phương thức tính bình phương của 10

Đề: Write a program that calls a method to find the square of 10.

Phân tích: tách phép tính ra phương thức riêng — bài học về "chia để trị", không phải chỉ để có kết quả.

// ===== BinhPhuong.java =====
public class BinhPhuong {

    public static int binhPhuong(int x) {
        return x * x;
    }

    public static void main(String[] args) {
        int kq = binhPhuong(10);
        System.out.println("Binh phuong cua 10 la: " + kq);
    }
}

Chạy:

Binh phuong cua 10 la: 100

Kiểm thử: binhPhuong(0) = 0; binhPhuong(-3) = 9; binhPhuong(46341) tràn int (âm) — dùng long nếu cần. Lỗi: public void binhPhuong(int x) { return x*x; } → unexpected return value; gọi binhPhuong() thiếu tham số → method binhPhuong cannot be applied to given types. Câu hỏi: vì sao binhPhuong phải static khi gọi từ main? (main là static, không có object.)


Bài 4 — 10 bội số đầu của 5

Đề: Write a program to display the first 10 multiples of 5.

Phân tích: biết trước số lần (10) → for. Bội số thứ i là 5*i.

// ===== BoiSoCua5.java =====
public class BoiSoCua5 {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            System.out.print(5 * i + " ");
        }
        System.out.println();
    }
}

Chạy:

5 10 15 20 25 30 35 40 45 50 

Bảng kiểm thử: 10 phần tử, phần tử cuối 50, tổng 275. Lỗi: for (int i = 0; i < 10; i++) mà in 5*i → bắt đầu bằng 0 và kết thúc 45 (vẫn 10 số nhưng sai đề "bội số đầu"). Câu hỏi: nếu đề là "các bội số của 5 nhỏ hơn 100" thì điều kiện vòng lặp đổi thành gì?


Bài 5 — 10 số nguyên tố đầu tiên

Đề: Write a program to list the first 10 prime numbers.

Phân tích: không biết trước số cần kiểm tra → while đếm đến 10; dùng hàm laNguyenTo.

// ===== MuoiNguyenTo.java =====
public class MuoiNguyenTo {

    public static boolean laNguyenTo(int n) {
        if (n < 2) return false;
        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) return false;
        }
        return true;
    }

    public static void main(String[] args) {
        int dem = 0;
        int so = 2;
        while (dem < 10) {
            if (laNguyenTo(so)) {
                System.out.print(so + " ");
                dem++;
            }
            so++;
        }
        System.out.println();
    }
}

Chạy:

2 3 5 7 11 13 17 19 23 29 

Trace 4 lượt đầu: so=2 → nguyên tố, dem=1; 3 → dem=2; 4 → bỏ; 5 → dem=3. Lỗi: dùng for (so = 2; so < 30; ...) → in 10 số nhưng "may mắn" đúng; nếu đổi 10 thành 15 sẽ thiếu. Phải đếm theo dem. Câu hỏi: vì sao dùng while mà không for? (Số lần lặp chưa biết trước.)


Bài 6 — Chẵn hay lẻ

Đề: accept a number and display whether it is odd or even.

// ===== ChanLe.java =====
import java.util.Scanner;

public class ChanLe {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Nhap so: ");
        int n = sc.nextInt();

        if (n % 2 == 0) System.out.println(n + " la so chan");
        else            System.out.println(n + " la so le");

        sc.close();
    }
}

Chạy: 7 → 7 la so le. Kiểm thử: 0 → chẵn; -4 → chẵn (-4 % 2 == 0); -3 → lẻ. Lỗi: n % 2 == 1 cho số âm → sai (-3 % 2 = -1). Luôn so với 0. Câu hỏi: vì sao % với số âm lại trả -1? (Java giữ dấu của số bị chia.)


Bài 7 — Kiểm tra nguyên âm

Đề: accept a character; nếu là a, e, i, o, u in You have input, Vowel, ngược lại This is not a Vowel.

Phân tích: nhập cả chữ hoa; chỉ lấy ký tự đầu nếu người dùng gõ nhiều ký tự.

// ===== NguyenAm.java =====
import java.util.Scanner;

public class NguyenAm {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Nhap mot ky tu: ");
        String s = sc.next();
        char c = Character.toLowerCase(s.charAt(0));

        switch (c) {
            case 'a': case 'e': case 'i': case 'o': case 'u':
                System.out.println("You have input, Vowel");
                break;
            default:
                System.out.println("This is not a Vowel");
        }
        sc.close();
    }
}

Chạy: e → You have input, Vowel; B → This is not a Vowel. Trace: "B" → toLowerCase('B') = 'b' → không khớp case nào → default. Lỗi: sc.next().charAt(0) khi người dùng chỉ gõ Enter → StringIndexOutOfBoundsException; dùng == so char thì được (char là nguyên thủy), nhưng so String thì không. Câu hỏi: vì sao dùng switch gộp case thay vì 5 câu if?


Bài 8 — Đếm cặp số bằng nhau liền kề

Đề (tiếng Việt): Viết chương trình đếm các cặp số bằng nhau liên tiếp trong dãy số nguyên.

Phân tích: duyệt i từ 0 đến n-2, so a[i] với a[i+1]. Bắt buộc i < n-1, nếu không sẽ truy cập a[n].

// ===== CapBangNhau.java =====
import java.util.Scanner;

public class CapBangNhau {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Nhap n: ");
        int n = sc.nextInt();
        if (n < 2) {
            System.out.println("Can it nhat 2 phan tu");
            sc.close();
            return;
        }

        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            System.out.print("a[" + i + "] = ");
            a[i] = sc.nextInt();
        }

        int dem = 0;
        for (int i = 0; i < n - 1; i++) {
            if (a[i] == a[i + 1]) dem++;
        }
        System.out.println("So cap bang nhau lien ke: " + dem);

        sc.close();
    }
}

Chạy với 1 1 2 2 2 3 4 4:

So cap bang nhau lien ke: 4

Trace:

i a[i] a[i+1] Bằng? dem
0 1 1 có 1
1 1 2 không 1
2 2 2 có 2
3 2 2 có 3
4 2 3 không 3
5 3 4 không 3
6 4 4 có 4

Kiểm thử: {5,5} → 1; {1,2,3} → 0; n=1 → báo cần ít nhất 2. Lỗi: i < n → ArrayIndexOutOfBoundsException; đếm "số phần tử trùng nhau" thay vì "số cặp" → sai bản chất. Câu hỏi: dãy 2 2 2 có mấy cặp? (2 cặp, không phải 3.)


Bài 9 — Phần tử không nhỏ hơn mọi số đứng trước

Đề: Cho dãy n số nguyên dương (2 ≤ n ≤ 50). Liệt kê các phần tử không nhỏ hơn mọi phần tử đứng trước nó (tính cả phần tử đầu).

Phân tích: giữ maxTruoc = max của đoạn đã duyệt; phần tử hiện tại ≥ maxTruoc thì in và cập nhật.

// ===== KhongNhoHonTruoc.java =====
import java.util.Scanner;

public class KhongNhoHonTruoc {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Nhap n (2-50): ");
        int n = sc.nextInt();
        if (n < 2 || n > 50) {
            System.out.println("n phai trong 2..50");
            sc.close();
            return;
        }

        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            System.out.print("a[" + i + "] = ");
            a[i] = sc.nextInt();
        }

        System.out.print("Ket qua: ");
        int maxTruoc = a[0];
        System.out.print(a[0] + " ");
        for (int i = 1; i < n; i++) {
            if (a[i] >= maxTruoc) {
                System.out.print(a[i] + " ");
                maxTruoc = a[i];
            }
        }
        System.out.println();

        sc.close();
    }
}

Chạy với 3 1 4 1 5 9 2 6:

Ket qua: 3 4 5 9 

Trace:

i a[i] maxTruoc trước a[i] >= max? In maxTruoc sau
0 3 — (luôn in phần tử đầu) 3 3
1 1 3 không — 3
2 4 3 có 4 4
3 1 4 không — 4
4 5 4 có 5 5
5 9 5 có 9 9
6 2 9 không — 9
7 6 9 không — 9

Kiểm thử: dãy tăng dần 1 2 3 → in cả 3; dãy giảm 5 4 3 → chỉ in 5; dãy bằng nhau 2 2 2 → in cả 3 (vì "không nhỏ hơn"). Lỗi: dùng > thay >= → bỏ mất phần tử bằng nhau; không in phần tử đầu → thiếu. Câu hỏi: vì sao phải cập nhật maxTruoc sau khi in?


Bài 10 — Ma trận chỉ gồm 0 và 1

Đề: Ma trận vuông A cấp n gồm các số nguyên dương. A được gọi là "ma trận đơn vị" nếu tất cả phần tử đều là 0 hoặc 1. Viết chương trình kiểm tra một ma trận có phải "ma trận đơn vị" hay không.

Lưu ý thuật ngữ: "ma trận đơn vị" trong toán học là ma trận có 1 trên đường chéo chính và 0 ở chỗ khác. Đề này định nghĩa khác (chỉ cần mọi phần tử ∈ {0,1}). Hãy làm đúng theo đề, và nếu muốn thì làm thêm phần "kiểm tra đơn vị đúng nghĩa" ở mục mở rộng.

// ===== MaTranDonVi.java =====
import java.util.Scanner;

public class MaTranDonVi {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Nhap n: ");
        int n = sc.nextInt();
        if (n <= 0) {
            System.out.println("n phai > 0");
            sc.close();
            return;
        }

        int[][] a = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print("a[" + i + "][" + j + "] = ");
                a[i][j] = sc.nextInt();
            }
        }

        boolean ok = true;
        for (int i = 0; i < n && ok; i++) {
            for (int j = 0; j < n; j++) {
                if (a[i][j] != 0 && a[i][j] != 1) {
                    ok = false;
                    break;                 // thoat vong trong
                }
            }
        }

        System.out.println(ok ? "La ma tran 0/1" : "Khong phai ma tran 0/1");

        sc.close();
    }
}

Chạy với

1 0 1
0 1 0
0 0 1

→ La ma tran 0/1.

Trace (ma trận có số 2):

i j a[i][j] Hợp lệ? ok
0 0 1 có true
0 1 2 không false → break

Kiểm thử: toàn 0 → đúng; có -1/2 → sai; n = 1 với a[0][0] = 5 → sai. Lỗi: break chỉ thoát vòng trong → dùng điều kiện i < n && ok để thoát cả ngoài; hoặc return ngay. Câu hỏi: vì sao đặt && ok trong điều kiện vòng ngoài thay vì kiểm tra sau?

Mở rộng — kiểm tra đơn vị đúng nghĩa:

boolean donVi = (a.length == n);
for (int i = 0; i < n && donVi; i++)
    for (int j = 0; j < n; j++)
        if (a[i][j] != (i == j ? 1 : 0)) { donVi = false; break; }

Bảng tổng hợp 10 bài

# Bài Điểm dễ sai nhất
1 Nhập tên nextInt rồi nextLine
2 Thứ trong tuần thiếu break
3 Bình phương quên static, quên return
4 Bội số của 5 bắt đầu i = 0
5 10 nguyên tố đếm bằng dem, không bằng khoảng
6 Chẵn lẻ % 2 == 1 với số âm
7 Nguyên âm chữ hoa, chuỗi rỗng
8 Cặp bằng nhau i < n - 1
9 Không nhỏ hơn trước >= vs >; in phần tử đầu
10 Ma trận 0/1 thoát cả hai vòng lặp

Checklist

🎧
Lồng tiếng tóm tắt bài giảng (ZeroTTS AI)
Đang đọc: Mai Chi (Nữ) · Thời lượng ~1–2 phút
ZeroTTS AI
00:00
--:--
📝 Lời thuyết minh (Tự động tô sáng câu đang đọc • Bấm vào câu để tua tới):
Đang nạp dữ liệu lời đọc...