Bỏ qua điều hướng, tới nội dung chính
Học C
Bài 7.617 phút đọc

Phân tích một bài toán

Sau bài này bạn sẽ làm được

  • Lập bảng phân tích đầy đủ cho một bài toán bất kỳ
  • Trả lời năm câu hỏi bắt buộc trước khi viết dòng code đầu tiên
  • Suy ra độ phức tạp cho phép từ ràng buộc thời gian
  • Chọn cấu trúc dữ liệu phù hợp với bài toán

Bài cuối của Phần 2 gom mọi thứ lại thành một công cụ dùng được ngay: bảng phân tích bài toán. Từ giờ tới hết khóa học, mọi bài tập có thuật toán đều bắt đầu bằng bảng này.

#Mô hình vào xử lý ra

Ba khối, mỗi khối có bộ câu hỏi riêng. Trả lời hết trước khi mở editor.

Mô hình này đơn giản tới mức có vẻ tầm thường, nhưng nó ép bạn tách rõ ba việc mà người mới hay trộn lẫn: dữ liệu đến từ đâu, làm gì với nó, và kết quả đi đâu.

#Năm câu hỏi bắt buộc

Đây là danh sách kiểm tra. Nếu chưa trả lời được cả năm thì chưa nên viết dòng mã nào.

CâuCâu hỏiNếu bỏ qua
1Dữ liệu vào chính xác là gì? Kiểu, miền giá trị, kích thước tối đa?Chọn sai kiểu dữ liệu, tràn số, hoặc cấp phát thiếu
2Dữ liệu ra chính xác là gì? Định dạng, làm tròn, đơn vị?Chạy đúng logic nhưng in sai định dạng, vẫn bị coi là sai
3Có những trường hợp biên nào?Chương trình chạy đúng với dữ liệu mẫu rồi hỏng với dữ liệu thật
4Ràng buộc thời gian và bộ nhớ là bao nhiêu?Viết xong mới biết thuật toán quá chậm, phải làm lại từ đầu
5Nếu dữ liệu vào sai thì làm gì?Chương trình dừng đột ngột hoặc cho kết quả vô nghĩa

#Bảng phân tích mẫu

Đề bài
Đọc file điểm sinh viên, mỗi dòng có dạng MSSV,HoTen,Diem. In ra 10 sinh viên có điểm cao nhất, sắp xếp giảm dần theo điểm.
MụcNội dung
VàoFile văn bản, mỗi dòng ba trường ngăn bằng dấu phẩy. Tối đa 10⁶ dòng. Điểm từ 0,0 tới 10,0
RaBảng 10 dòng gồm hạng, mã số, họ tên, điểm. Điểm hiện hai chữ số thập phân, các cột căn thẳng
Ràng buộcBộ nhớ tối đa 256 MB. Mỗi bản ghi khoảng 84 byte nên 10⁶ bản ghi chiếm khoảng 84 MB, vẫn chứa vừa
Trường hợp biênFile rỗng. Ít hơn 10 sinh viên. Dòng sai định dạng. Dòng thiếu trường. Điểm ngoài khoảng hợp lệ. Mã số trùng nhau. Điểm bằng nhau ở vị trí thứ 10
Thuật toánCách A: sắp xếp toàn bộ rồi lấy 10 đầu, O(n log n). Cách B: dùng đống nhỏ nhất kích thước 10, O(n log 10) tức O(n). Chọn cách B
Cấu trúc dữ liệuMột struct cho bản ghi, một đống nhỏ nhất cố định 10 phần tử
Xử lý lỗiKhông mở được file thì báo ra luồng lỗi chuẩn rồi thoát với mã khác 0. Dòng sai định dạng thì cảnh báo, bỏ qua, và đếm số dòng đã bỏ

Mã giả tương ứng

HÀM top_10(ten_file)
    NẾU không mở được ten_file THÌ
        BÁO LỖI và THOÁT
    HẾT NẾU

    dong_loi ← 0
    dong     ← đống nhỏ nhất rỗng, sức chứa 10

    VỚI MỖI dong_van_ban TRONG file LÀM
        NẾU không tách được thành ba trường THÌ
            dong_loi ← dong_loi + 1
            BỎ QUA dòng này
        HẾT NẾU

        NẾU điểm nằm ngoài khoảng 0 đến 10 THÌ
            dong_loi ← dong_loi + 1
            BỎ QUA dòng này
        HẾT NẾU

        NẾU đống chưa đủ 10 phần tử THÌ
            THÊM bản ghi vào đống
        NGƯỢC LẠI NẾU điểm > điểm nhỏ nhất trong đống THÌ
            BỎ phần tử nhỏ nhất
            THÊM bản ghi vào đống
        HẾT NẾU
    HẾT VỚI

    SẮP XẾP đống giảm dần theo điểm
    IN bảng kết quả
    NẾU dong_loi > 0 THÌ CẢNH BÁO số dòng đã bỏ qua
HẾT HÀM

Đống nhỏ nhất sẽ được học ở Chương 23. Ở đây bạn chỉ cần thấy: khi bảng phân tích chỉ ra rằng chỉ cần 10 kết quả trong một triệu bản ghi, nó dẫn thẳng tới lựa chọn cấu trúc dữ liệu phù hợp.

#Chọn cấu trúc dữ liệu

Bảng phân tích không chỉ chọn thuật toán, nó còn chọn cả cấu trúc dữ liệu. Bảng dưới đây là bản rút gọn để dùng ngay, còn chi tiết đầy đủ nằm ở Phần 10.

Nhu cầu chínhNên dùngHọc ở
Truy cập theo chỉ số, kích thước biết trướcMảngChương 9
Kích thước thay đổi lúc chạyMảng độngChương 14
Thêm và xóa ở đầu rất nhiềuDanh sách liên kếtChương 21
Vào sau ra trướcNgăn xếpChương 22
Vào trước ra trướcHàng đợiChương 23
Luôn lấy phần tử lớn nhất hoặc nhỏ nhấtĐốngChương 23
Tra cứu theo khóa rất nhanhBảng bămChương 25
Tra cứu theo khóa và cần thứ tựCây tìm kiếm nhị phânChương 24

Quy trình rút gọn để dùng hằng ngày

1. Vào là gì?           kiểu, miền, kích thước tối đa
2. Ra là gì?            định dạng, làm tròn
3. Biên nào?            n=0, n=1, trùng nhau, âm, tràn
4. Ràng buộc?           thời gian và bộ nhớ  ->  suy ra độ phức tạp cho phép
5. Dữ liệu sai thì sao? bỏ qua, báo lỗi, hay dừng hẳn

Rồi mới: nghĩ hai hướng giải -> chọn -> viết mã giả -> cài đặt -> kiểm thử

#Tổng kết Phần 2

Bạn vừa hoàn thành Phần 2. Đây là những gì đã tích lũy qua hai chương.

  • Chương 6: ba loại vòng lặp và khi nào dùng cái nào, ba thành phần bắt buộc, bảy nguyên nhân chạy vô hạn, bốn công cụ điều khiển, và một bài học về bộ nhớ đệm mà nhiều người học C nhiều năm vẫn không biết.
  • Chương 7: quy trình sáu bước, năm tính chất của thuật toán, mã giả, lưu đồ, Big-O kèm bảng quy đổi ra thời gian thật, và bảng phân tích bài toán.

Phần 3 sẽ vào hàm: cách chia chương trình thành các khối độc lập, khung ngăn xếp thật sự hoạt động ra sao, và đệ quy. Đó là bước chuẩn bị trực tiếp cho Phần 5 về con trỏ, chặng khó nhất của cả khóa học.

Tự làm thử

  1. Lập bảng phân tích đầy đủ cho bài toán: tìm số xuất hiện nhiều nhất trong mảng 10⁷ phần tử, biết giá trị nằm trong khoảng 0 tới 1000.
  2. Lập bảng phân tích cho bài toán kiểm tra chuỗi ngoặc hợp lệ với ba loại ngoặc.
  3. Lập bảng phân tích cho bài toán tìm đường đi ngắn nhất trong mê cung 1000 nhân 1000.
  4. Lập bảng phân tích cho bài toán gộp hai file đã sắp xếp thành một file sắp xếp, biết mỗi file 10 GB còn bộ nhớ chỉ 1 GB. Chú ý câu hỏi số 4.
  5. Cài đặt trọn vẹn bài toán top 10 sinh viên, dùng mảng thay cho đống trước, đo thời gian với file một triệu dòng.
  6. Lấy một bài tập bất kỳ bạn đã làm ở Phần 1, lập bảng phân tích cho nó, và xem có trường hợp biên nào bạn đã bỏ sót.

Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.

Tóm tắt

  • Mô hình vào xử lý ra tách ba nhóm lỗi khác nhau, giúp khoanh vùng nhanh khi chương trình sai.
  • Năm câu hỏi bắt buộc: vào là gì, ra là gì, biên nào, ràng buộc gì, dữ liệu sai thì sao.
  • Ràng buộc thời gian quyết định độ phức tạp cho phép, và độ phức tạp quyết định thuật toán.
  • Bảng phân tích nên ghi ít nhất hai hướng giải rồi mới chọn một.
  • Bảng phân tích cũng dẫn tới việc chọn cấu trúc dữ liệu phù hợp.
  • Với n nhỏ, mảng đơn giản thường thắng mọi cấu trúc tinh vi nhờ bộ nhớ đệm.