Lab 01 — Môi trường, mảng, vòng lặp

LAB 01 — GIẢI CHI TIẾT (MÔI TRƯỜNG, MẢNG, VÒNG LẶP)

Nguồn: JavaLabStart_.pdf. Bám theo lý thuyết buổi 1, 2, 4, 7 trong bai-giang-java. Cách dùng: đọc mục 0–4 của từng bài, tự viết, rồi so với mục 5. Đừng đọc mục 5 trước.

Phần A — Cài đặt môi trường (mục 2.1, 2.2 của đề)

Đây là bài không có code, nhưng là bài chấm điểm đầu tiên: nếu javac không chạy, mọi bài sau bằng 0.

A.0 Đề bài

Cài JDK, thêm ...\jdk\bin vào Path, tạo thư mục D:\THLTHDT, biên dịch và chạy chương trình đầu tiên từ cmd.

A.1 Yêu cầu ẩn

A.2 Kiểm tra đúng/sai

Lệnh Kết quả đúng Nếu sai
java -version java version "17.0.x" Chưa có JDK/JRE
javac -version javac 17.0.x Có JRE nhưng chưa có JDK, hoặc chưa thêm bin vào Path
cd \THLTHDT Không báo lỗi Chưa tạo thư mục
javac Chao.java Im lặng = thành công In lỗi cú pháp → sửa theo mục A.3
java Chao In ra dòng chữ Could not find or load main class → sai tên lớp hoặc gõ .class

A.3 Ba lỗi môi trường hay gặp nhất

Hiện tượng Nguyên nhân Cách sửa
'javac' is not recognized as an internal or external command bin chưa vào Path Thêm C:\Program Files\Java\jdk-17\bin; mở lại cmd
error: file not found: Chao.java Notepad lưu thành Chao.java.txt Save as type = All Files
Error: Main method not found in class Chao main sai chữ ký (thiếu String[] args hoặc static) Sửa đúng public static void main(String[] args)

Bài A1 — Chao2 (mục 2.3)

0. Đề bài

Viết chương trình in Chao <Tên>, với <Tên> truyền vào từ dòng lệnh.

1. Yêu cầu ẩn

2. Input → Output

Vào Kiểu Ghi chú Ra
args String[] có thể rỗng Chao <ten> hoặc thông báo thiếu tham số

3. Thiết kế

  1. Kiểm tra args.length == 0 → in hướng dẫn, return.
  2. Nối toàn bộ args bằng dấu cách (dùng vòng lặp, không dùng String.join vì chưa học).
  3. In "Chao " + ten.

4. Code từng bước

Bước 1 — khung chương trình và kiểm tra tham số:

public class Chao2 {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Cach dung: java Chao2 <ten>");
            return;                      // thoát sớm, không chạy tiếp
        }
    }
}

Tự kiểm tra: chạy java Chao2 phải in hướng dẫn, không lỗi.

Bước 2 — nối các tham số và in:

        String ten = "";
        for (int i = 0; i < args.length; i++) {
            ten += args[i];
            if (i < args.length - 1) ten += " ";   // thêm dấu cách giữa các từ
        }
        System.out.println("Chao " + ten);

5. Lời giải hoàn chỉnh

// ===== Chao2.java =====
public class Chao2 {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Cach dung: java Chao2 <ten>");
            return;
        }

        String ten = "";
        for (int i = 0; i < args.length; i++) {
            ten += args[i];
            if (i < args.length - 1) ten += " ";
        }
        System.out.println("Chao " + ten);
    }
}

6. Cách chạy

javac Chao2.java
java Chao2 Nam
java Chao2 Nguyen Van An
java Chao2

7. Kết quả chạy mẫu

Chao Nam
Chao Nguyen Van An
Cach dung: java Chao2 <ten>

8. Bảng kiểm thử

# Input Kỳ vọng Thực tế
1 java Chao2 Nam Chao Nam đạt
2 java Chao2 Nguyen Van An Chao Nguyen Van An đạt
3 java Chao2 in hướng dẫn, không lỗi đạt
4 java Chao2 "" (chuỗi rỗng) Chao đạt

9. Trace

args = ["Nguyen","Van","An"]:

Lượt i args[i] ten sau khi nối Có thêm dấu cách?
0 Nguyen Nguyen có → Nguyen
1 Van Nguyen Van có → Nguyen Van
2 An Nguyen Van An không (i = length-1)

10. Lỗi thường gặp

Code sai Thông báo Nguyên nhân Sửa
String ten = args[0]; khi không truyền ArrayIndexOutOfBoundsException: 0 Không kiểm tra length if (args.length > 0)
public static void main(String args) Error: Main method not found in class Chao2 Thiếu [] String[] args
System.out.print("Chao " + args); Chao [Ljava.lang.String;@... In cả mảng In từng phần tử
Lưu Chao2.java.txt file not found Notepad tự thêm đuôi Save as All Files
java Chao2.class Could not find or load main class Chao2.class Khi chạy không ghi đuôi java Chao2

11. Câu hỏi kiểm tra hiểu

  1. Vì sao args có sẵn dù ta không khai báo giá trị cho nó?
  2. Nếu chạy java Chao2 1 2 3, args.length bằng mấy?
  3. Vì sao phải return sau khi in hướng dẫn?

12. Mở rộng

TỰ KIỂM TRA 60 GIÂY: args là gì? Kiểm tra gì trước khi dùng args[0]? Khi chạy có gõ .class không?


Bài A2 — Đọc một số có một chữ số (mục 2.3)

0. Đề bài

Nhập một số có một chữ số (0–9), in ra cách đọc bằng chữ.

1. Yêu cầu ẩn

2. Input → Output

Vào Kiểu Miền Ra
số int 0..9 tên chữ: khong, mot, hai, ... chin

3. Thiết kế

Dùng switch vì là so bằng với danh sách giá trị rời rạc (buổi 6). default xử lý ngoài miền.

4. Code từng bước

Bước 1 — nhập số, kiểm tra miền:

Scanner sc = new Scanner(System.in);
System.out.print("Nhap mot chu so (0-9): ");
int n = sc.nextInt();
if (n < 0 || n > 9) {
    System.out.println("Khong hop le");
    return;
}

Bước 2 — switch in tên:

switch (n) {
    case 0: System.out.println("khong"); break;
    case 1: System.out.println("mot");   break;
    case 2: System.out.println("hai");   break;
    case 3: System.out.println("ba");    break;
    case 4: System.out.println("bon");   break;
    case 5: System.out.println("nam");   break;
    case 6: System.out.println("sau");   break;
    case 7: System.out.println("bay");   break;
    case 8: System.out.println("tam");   break;
    case 9: System.out.println("chin");  break;
}

5. Lời giải hoàn chỉnh

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

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

        if (n < 0 || n > 9) {
            System.out.println("Khong hop le");
        } else {
            switch (n) {
                case 0: System.out.println("khong"); break;
                case 1: System.out.println("mot");   break;
                case 2: System.out.println("hai");   break;
                case 3: System.out.println("ba");    break;
                case 4: System.out.println("bon");   break;
                case 5: System.out.println("nam");   break;
                case 6: System.out.println("sau");   break;
                case 7: System.out.println("bay");   break;
                case 8: System.out.println("tam");   break;
                default: System.out.println("chin"); break;
            }
        }
        sc.close();
    }
}

Chú ý: default ở đây chỉ còn nhận 9 vì đã chặn ngoài miền — hợp lệ nhưng dễ gây nhầm. Cách an toàn hơn: vẫn viết case 9: ... break; và default: System.out.println("Khong hop le");.

6. Cách chạy

javac DocSo.java
java DocSo

7. Kết quả chạy mẫu

Nhap mot chu so (0-9): 7
bay

8. Bảng kiểm thử

# Input Kỳ vọng
1 7 bay
2 0 khong
3 -1 Khong hop le
4 10 Khong hop le

9. Trace

n = 7 → vào case 7 → in bay → gặp break → thoát switch. Nếu bỏ tất cả break: n = 7 in bay tam chin (fall-through, buổi 6).

10. Lỗi thường gặp

Code sai Thông báo Sửa
switch (n) { case 0: ... } thiếu break Không lỗi, in thừa Thêm break
if (n = 7) incompatible types: int cannot be converted to boolean ==
Quên import java.util.Scanner; cannot find symbol: class Scanner Thêm import
Nhập 7.5 InputMismatchException Chỉ nhập số nguyên

11. Câu hỏi kiểm tra hiểu

  1. Vì sao bài này dùng switch mà không dùng 10 câu if?
  2. Nếu bỏ default, nhập 9 thì in gì?
  3. break bỏ đi thì chương trình sai ở đâu?

12. Mở rộng


Bài A3 — Hình tròn (mục 2.3)

0. Đề bài

Nhập bán kính, tính và in diện tích, chu vi hình tròn.

1. Yêu cầu ẩn

2. Input → Output

Vào Kiểu Ràng buộc Ra
r double r > 0 diện tích πr², chu vi 2πr

3. Thiết kế

  1. Nhập r.
  2. Kiểm tra r <= 0 → báo lỗi, thoát.
  3. Tính dienTich = Math.PI * r * r, chuVi = 2 * Math.PI * r.
  4. In, làm tròn 2 chữ số: Math.round(x * 100) / 100.0.

4. Code từng bước

Bước 1 — nhập và kiểm tra:

Scanner sc = new Scanner(System.in);
System.out.print("Nhap ban kinh: ");
double r = sc.nextDouble();
if (r <= 0) {
    System.out.println("Ban kinh phai duong");
    return;
}

Bước 2 — tính và in:

double dienTich = Math.PI * r * r;
double chuVi    = 2 * Math.PI * r;

System.out.println("Dien tich: " + Math.round(dienTich * 100) / 100.0);
System.out.println("Chu vi   : " + Math.round(chuVi * 100) / 100.0);

5. Lời giải hoàn chỉnh

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

public class HinhTron {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Nhap ban kinh: ");
        double r = sc.nextDouble();

        if (r <= 0) {
            System.out.println("Ban kinh phai duong");
            sc.close();
            return;
        }

        double dienTich = Math.PI * r * r;
        double chuVi    = 2 * Math.PI * r;

        System.out.println("Dien tich: " + Math.round(dienTich * 100) / 100.0);
        System.out.println("Chu vi   : " + Math.round(chuVi * 100) / 100.0);

        sc.close();
    }
}

6. Cách chạy

javac HinhTron.java
java HinhTron

7. Kết quả chạy mẫu

Nhap ban kinh: 3
Dien tich: 28.27
Chu vi   : 18.85

Kiểm tra tay: π·3² = 9π ≈ 28.2743 → 28.27 ✓; 2π·3 = 6π ≈ 18.8496 → 18.85 ✓.

8. Bảng kiểm thử

# Input Kỳ vọng
1 3 28.27 / 18.85
2 1 3.14 / 6.28
3 0 "Ban kinh phai duong"
4 -2 "Ban kinh phai duong"

9. Trace

Lệnh r dienTich chuVi
nextDouble() 3.0 — —
π*r*r 3.0 28.274333882308138 —
2*π*r 3.0 28.274333882308138 18.84955592153876
in làm tròn 28.27 18.85

10. Lỗi thường gặp

Code sai Thông báo Sửa
int r = sc.nextInt(); rồi Math.PI*r*r Kết quả mất phần lẻ double
r * r * 3.14 Không lỗi, nhưng kém chính xác Dùng Math.PI
Math.round(x) In 28.0 thay vì 28.27 Math.round(x*100)/100.0
Thiếu import java.util.Scanner cannot find symbol Thêm import

11. Câu hỏi kiểm tra hiểu

  1. Vì sao phải ép Math.round(...) về double bằng / 100.0 chứ không / 100?
  2. Nếu không kiểm tra r <= 0, chương trình in gì với r = -2? Có sai không?
  3. Math.PI thuộc lớp nào, có cần import không?

12. Mở rộng


Bài A4 — Sắp xếp mảng ngẫu nhiên (mục 2.3)

0. Đề bài

Tạo mảng số nguyên ngẫu nhiên, sắp xếp tăng dần và in ra.

1. Yêu cầu ẩn

2. Input → Output

Vào Kiểu Miền Ra
n int 1..100 mảng trước và sau khi sắp xếp

3. Thiết kế

  1. Sinh n số bằng (int)(Math.random() * 100) → 0..99.
  2. In mảng ban đầu.
  3. Bubble sort (buổi 4).
  4. In mảng sau khi sắp xếp.

4. Code từng bước

Bước 1 — sinh mảng và in:

int n = 10;
int[] a = new int[n];
for (int i = 0; i < n; i++) {
    a[i] = (int) (Math.random() * 100);
}
for (int i = 0; i < n; i++) System.out.print(a[i] + " ");
System.out.println();

Bước 2 — sắp xếp nổi bọt:

for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < n - 1 - i; j++) {
        if (a[j] > a[j + 1]) {
            int tmp = a[j];
            a[j] = a[j + 1];
            a[j + 1] = tmp;
        }
    }
}

Bước 3 — in lại.

5. Lời giải hoàn chỉnh

// ===== SapXepNgauNhien.java =====
public class SapXepNgauNhien {
    public static void main(String[] args) {
        int n = 10;
        int[] a = new int[n];

        // 1. sinh ngau nhien 0..99
        for (int i = 0; i < n; i++) {
            a[i] = (int) (Math.random() * 100);
        }

        System.out.print("Truoc khi sap xep: ");
        for (int i = 0; i < n; i++) System.out.print(a[i] + " ");
        System.out.println();

        // 2. sap xep noi bot tang dan
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                }
            }
        }

        System.out.print("Sau khi sap xep : ");
        for (int i = 0; i < n; i++) System.out.print(a[i] + " ");
        System.out.println();
    }
}

6. Cách chạy

javac SapXepNgauNhien.java
java SapXepNgauNhien

7. Kết quả chạy mẫu (một lần chạy, số sẽ khác mỗi lần)

Truoc khi sap xep: 42 7 91 15 63 3 88 24 56 71 
Sau khi sap xep : 3 7 15 24 42 56 63 71 88 91 

Không được lấy dãy số này làm "kết quả đúng" — hãy kiểm tra tính chất: sau khi sắp xếp, dãy không giảm và có đúng 10 phần tử như ban đầu (so khớp tổng hai dãy phải bằng nhau).

8. Bảng kiểm thử

# Tình huống Kỳ vọng
1 n = 10 bình thường dãy sau sắp xếp không giảm, cùng đa tập phần tử
2 n = 1 in 1 phần tử, không lỗi
3 Mảng toàn số bằng nhau không đổi
4 n = 0 không in gì, không lỗi (vòng lặp không chạy)

9. Trace (mảng nhỏ {3, 1, 2} để dễ thấy)

Lượt i j So sánh Đổi chỗ Mảng
— — — — 3 1 2
0 0 3 > 1 có 1 3 2
0 1 3 > 2 có 1 2 3
1 0 1 > 2 không 1 2 3

10. Lỗi thường gặp

Code sai Thông báo / hiện tượng Sửa
a[j] = a[j+1]; a[j+1] = a[j]; Hai phần tử bằng nhau Dùng tmp
j < n - i ArrayIndexOutOfBoundsException tại a[j+1] j < n - 1 - i
(int) Math.random() * 100 Luôn bằng 0 (int)(Math.random()*100)
for (i = 0; i < n; i++) không khai báo i cannot find symbol for (int i = ...)

11. Câu hỏi kiểm tra hiểu

  1. Vì sao Math.random() phải nhân trước rồi mới ép (int)?
  2. Vì sao vòng trong chỉ chạy n-1-i lần?
  3. Nếu mảng đã sắp xếp sẵn, thuật toán còn đổi chỗ lần nào không?

12. Mở rộng

TỰ KIỂM TRA 60 GIÂY: vì sao cần biến tmp? Math.random() trả về kiểu gì? Vì sao phải in cả trước và sau?


Bài A5 — Tính n! với n từ dòng lệnh (mục 2.4, Bài 1)

0. Đề bài

Tính giai thừa n! với n truyền vào từ dòng lệnh.

1. Yêu cầu ẩn

2. Input → Output

Vào Kiểu Ràng buộc Ra
args[0] String → int 0 ≤ n ≤ 20 (với long) n!

3. Thiết kế

  1. Kiểm tra có tham số.
  2. int n = Integer.parseInt(args[0]);
  3. Nếu n < 0 → báo lỗi, thoát.
  4. long kq = 1; for (int i = 2; i <= n; i++) kq *= i;
  5. In.

4. Code từng bước

Bước 1 — đọc và kiểm tra:

if (args.length == 0) {
    System.out.println("Cach dung: java GiaiThua <n>");
    return;
}
int n = Integer.parseInt(args[0]);
if (n < 0) {
    System.out.println("n phai >= 0");
    return;
}

Bước 2 — tính bằng long và in:

long kq = 1;
for (int i = 2; i <= n; i++) {
    kq *= i;
}
System.out.println(n + "! = " + kq);

5. Lời giải hoàn chỉnh

// ===== GiaiThua.java =====
public class GiaiThua {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Cach dung: java GiaiThua <n>");
            return;
        }

        int n = Integer.parseInt(args[0]);
        if (n < 0) {
            System.out.println("n phai >= 0");
            return;
        }

        long kq = 1;
        for (int i = 2; i <= n; i++) {   // bat dau tu 2: 0! va 1! deu = 1
            kq *= i;
        }

        System.out.println(n + "! = " + kq);
    }
}

6. Cách chạy

javac GiaiThua.java
java GiaiThua 5
java GiaiThua 0
java GiaiThua 20

7. Kết quả chạy mẫu

5! = 120
0! = 1
20! = 2432902008176640000

Kiểm tra: 5! = 120 ✓; 20! = 2 432 902 008 176 640 000 ✓ (vừa long).

8. Bảng kiểm thử

# Input Kỳ vọng
1 5 5! = 120
2 0 0! = 1
3 -3 n phai >= 0
4 13 6227020800 (chỉ đúng nếu dùng long)

9. Trace

n = 5:

i kq trước kq sau
— 1 1
2 1 2
3 2 6
4 6 24
5 24 120

10. Lỗi thường gặp

Code sai Thông báo / hiện tượng Sửa
int kq = 1; với n = 13 Ra số âm (-559939584) do tràn long
Integer.parseint(args[0]) cannot find symbol: method parseint parseInt
for (i = 1; i < n; i++) Thiếu một thừa số (5! ra 24) i <= n
Truyền chữ: java GiaiThua abc NumberFormatException Kiểm tra dữ liệu (nâng cao: try/catch)
Không kiểm tra args.length ArrayIndexOutOfBoundsException Kiểm tra trước

11. Câu hỏi kiểm tra hiểu

  1. Vì sao vòng lặp bắt đầu từ 2 mà vẫn đúng với 0! và 1!?
  2. Vì sao 13! là "cột mốc" của kiểu int?
  3. n = 21 thì long có đủ không? (21! ≈ 5.1×10¹⁹ > 9.2×10¹⁸ → tràn)

12. Mở rộng


Bài A6 — Số nguyên tố trong mảng (mục 2.4, Bài 2)

0. Đề bài

Nhập mảng n số nguyên, liệt kê các số nguyên tố có trong mảng; bổ sung thông báo mảng có bao nhiêu số nguyên tố.

1. Yêu cầu ẩn

2. Input → Output

Vào Kiểu Miền Ra
n int 1..100 danh sách số nguyên tố + số lượng
a[i] int bất kỳ

3. Thiết kế

4. Code từng bước

Bước 1 — hàm kiểm tra nguyên tố (thuộc lòng):

public static boolean laNguyenTo(int n) {
    if (n < 2) return false;                 // 0, 1 va so am
    for (int i = 2; i <= Math.sqrt(n); i++) {
        if (n % i == 0) return false;        // co uoc -> khong nguyen to
    }
    return true;
}

Bước 2 — nhập mảng:

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

Bước 3 — duyệt, in và đếm:

int dem = 0;
for (int i = 0; i < n; i++) {
    if (laNguyenTo(a[i])) {
        System.out.print(a[i] + " ");
        dem++;
    }
}
System.out.println("\nCo " + dem + " so nguyen to");

5. Lời giải hoàn chỉnh

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

public class NguyenToTrongMang {

    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) {
        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];
        for (int i = 0; i < n; i++) {
            System.out.print("a[" + i + "] = ");
            a[i] = sc.nextInt();
        }

        System.out.print("Cac so nguyen to: ");
        int dem = 0;
        for (int i = 0; i < n; i++) {
            if (laNguyenTo(a[i])) {
                System.out.print(a[i] + " ");
                dem++;
            }
        }
        System.out.println();
        System.out.println("Co " + dem + " so nguyen to");

        sc.close();
    }
}

6. Cách chạy

javac NguyenToTrongMang.java
java NguyenToTrongMang

7. Kết quả chạy mẫu

Nhap n: 6
a[0] = 2
a[1] = 3
a[2] = 4
a[3] = 5
a[4] = 10
a[5] = 11
Cac so nguyen to: 2 3 5 11 
Co 4 so nguyen to

8. Bảng kiểm thử

# Mảng Kỳ vọng
1 2 3 4 5 10 11 2 3 5 11, 4 số
2 0 1 không có, 0 số
3 -7 7 7, 1 số
4 97 97, 1 số

9. Trace

laNguyenTo(11): i chạy 2, 3 (√11 ≈ 3.31), cả hai 11 % i ≠ 0 → true. laNguyenTo(9): i = 2 không chia hết; i = 3, 9 % 3 == 0 → false ngay.

10. Lỗi thường gặp

Code sai Hiện tượng Sửa
if (n == 1) return false; Số 0 và số âm bị coi là nguyên tố if (n < 2) return false;
for (i = 2; i < n; i++) Chạy chậm nhưng vẫn đúng Dùng Math.sqrt
return true; khi chia hết Kết quả ngược return false;
Quên break khi đếm Không ảnh hưởng, nhưng khó đọc Tách hàm
n <= 0 vẫn new int[n] NegativeArraySizeException Kiểm tra trước

11. Câu hỏi kiểm tra hiểu

  1. Vì sao chỉ cần duyệt đến √n mà vẫn kết luận đúng?
  2. Vì sao 1 không phải số nguyên tố?
  3. Nếu mảng toàn số âm, hàm trả gì? Vì sao?

12. Mở rộng


Bài A7 — Fibonacci trong mảng (mục 2.4, Bài 3)

0. Đề bài

Nhập mảng n số nguyên, liệt kê các số Fibonacci có trong mảng.

1. Yêu cầu ẩn

2. Input → Output

Vào Kiểu Ra
mảng n số nguyên int[] các phần tử là số Fibonacci (theo thứ tự trong mảng)

3. Thiết kế

Cách đơn giản và đúng: với mỗi a[i], kiểm tra bằng hàm laFibonacci sinh dãy từ 0, 1 đến khi ≥ giá trị cần kiểm tra.

4. Code từng bước

Bước 1 — hàm kiểm tra:

public static boolean laFibonacci(int x) {
    if (x < 0) return false;
    int a = 0, b = 1;
    while (a < x) {
        int tiep = a + b;
        a = b;
        b = tiep;
    }
    return a == x;          // dung lai khi a >= x
}

Bước 2 — duyệt mảng, in.

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

5. Lời giải hoàn chỉnh

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

public class FibonacciTrongMang {

    public static boolean laFibonacci(int x) {
        if (x < 0) return false;
        int a = 0, b = 1;
        while (a < x) {
            int tiep = a + b;
            a = b;
            b = tiep;
        }
        return a == x;
    }

    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];
        for (int i = 0; i < n; i++) {
            System.out.print("a[" + i + "] = ");
            a[i] = sc.nextInt();
        }

        System.out.print("Cac so Fibonacci: ");
        for (int i = 0; i < n; i++) {
            if (laFibonacci(a[i])) System.out.print(a[i] + " ");
        }
        System.out.println();

        sc.close();
    }
}

6. Cách chạy

javac FibonacciTrongMang.java
java FibonacciTrongMang

7. Kết quả chạy mẫu

Nhap n: 7
a[0] = 1
a[1] = 2
a[2] = 4
a[3] = 5
a[4] = 8
a[5] = 13
a[6] = 20
Cac so Fibonacci: 1 2 5 8 13 

8. Bảng kiểm thử

# Giá trị laFibonacci
1 0 true
2 1 true
3 4 false
4 13 true
5 -3 false

9. Trace laFibonacci(8)

Bước a b a < 8?
đầu 0 1 đúng
1 1 1 đúng
2 1 2 đúng
3 2 3 đúng
4 3 5 đúng
5 5 8 đúng
6 8 13 sai → dừng, a == 8 → true

10. Lỗi thường gặp

Code sai Hiện tượng Sửa
while (true) { ... } không điều kiện dừng Treo với số không phải Fibonacci Dừng khi a >= x
if (a == x) return true; đặt trong vòng lặp không có break Không sai nhưng thừa Kiểm tra sau vòng lặp
Dùng a < x mà quên trường hợp x = 0 0 vẫn đúng vì vòng lặp không chạy Kiểm tra a == 0
Tràn int khi sinh dãy lớn Số âm xuất hiện Dùng long hoặc chặn x

11. Câu hỏi kiểm tra hiểu

  1. Vì sao vòng lặp dừng ở a < x mà vẫn kiểm tra đúng x = 8?
  2. Nếu x = 1, vòng lặp chạy mấy lần?
  3. Vì sao phải kiểm tra x < 0 trước?

12. Mở rộng


Checklist nộp Lab 01

🎧
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...