Hệ Thống Phát Hiện Đạo Văn Dựa Trên Thuật Toán Dãy Con Chung Dài Nhất

Mục Tiêu Dự Án

Hoạt động này tập trung vào việc xây dựng một giải pháp tự động hóa để xác định tỷ lệ trùng lặp nội dung giữa hai file văn bản. Cụ thể, chương trình cần nhận diện sự giống nhau giữa một tài liệu gốc và phiên bản đã bị chỉnh sửa (thêm/xóa/sửa đổi) để đưa ra chỉ số định lượng.

Yêu Cầu Đầu Vào Và Đầu Ra

  • Đầu vào: Nhận đường dẫn tuyệt đối của ba file thông qua tham số dòng lệnh:
    1. File văn bản gốc.
    2. File văn bản nghi ngờ sao chép.
    3. File đích để ghi kết quả phân tích.
  • Kết quả: Giá trị số thực hiển thị tỷ lệ tương đồng, được làm tròn đến hai chữ số thập phân.
  • Công cụ mẫu: Sử dụng dữ liệu mẫu đã cung cấp trong lớp học để kiểm tra khả năng xử lý các trường hợp chèn hoặc xóa ký tự.

Tổng Quan Kiến Trúc Phần Mềm

Cấu trúc mã nguồn được thiết kế theo mô hình phân tầng rõ ràng nhằm đảm bảo tính mở rộng và dễ bảo trì:

Tầng (Layer) Thành Phần Chính Nhiệm Vụ Chức Năng
Lớp Ứng Dụng (Application) Main Xử lý giao tiếp với người dùng, đọc biến môi trường, gọi API lõi và xuất báo cáo.
Lớp Nghiệp Vụ (Business Logic) Class ContentAnalyzer Thực thi thuật toán so khớp, quản lý các phương thức tính toán độ tương tự khác nhau.
Lớp Tiện Ích (Utility) Module xử lý chuỗi Mã hóa, chuẩn hóa ký tự và loại bỏ khoảng trắng thừa trước khi so sánh.

Chi Tiết Thuật Toán Tính Tương Đồng

Hai đoạn văn bản được so sánh dựa trên độ dài của Dãy Con Chung Dài Nhất (Longest Common Subsequence - LCS). Tỷ lệ trùng lặp được tính bằng công thức:

$$ \text{Tỷ Lệ} = \frac{\text{Độ Dài LCS}}{\text{Độ Dài Văn Bản Gốc}} $$

Các Biến Thể Của Hàm Tính LCS

  1. Phân tích tiêu chuẩn (getLCSScore): Dùng ma trận 2 chiều. Phù hợp cho văn bản ngắn vì độ phức tạp không gian là $O(N \times M)$.
  2. Tối ưu bộ nhớ (optimizeMemoryLCS): Chỉ giữ lại cột trước đó để cập nhật trạng thái hiện tại. Độ phức tạp không gian giảm xuống $O(\min(N, M))$.
  3. Tối ưu khối (blockChunkLCS): Chia nhỏ văn bản thành các đoạn (chunk) để tính toán cục bộ. Giải quyết vấn đề tràn bộ nhớ trên file lớn.

Đánh Giá Hiệu Năng

Các thử nghiệm đo lường hiệu suất cho thấy sự cải thiện đáng kể về tài nguyên hệ thống khi áp dụng các biến thể tối ưu:

  • Độ phức tạp thời gian: Giữ nguyên $O(N \times M)$ cho tất cả các biến thể, nhưng hằng số thực thi nhỏ hơn nhờ tận dụng CPU cache.
  • Độ phức tạp không gian: Giảm thiểu từ vài MB (đối với file lớn 20k ký tự ở bản tiêu chuẩn) xuống còn vài KB (ở bản tối ưu).
  • Khả năng chịu tải: Phiên bản tối ưu thứ 3 có thể xử lý hàng chục nghìn ký tự mà không gây lỗi tràn bộ nhớ stack.

Mã Nguồn Kiểm Thử Đơn Vị (Unit Test)

Dưới đây là các kịch bản kiểm thử đã được viết lại để xác minh tính đúng đắn của hàm tính toán, sử dụng khung thử nghiệm MSTest.

1. Xử Lý Trường Hợp Rỗng

TEST_CASE(Test_Null_Input_Handling) {
    // Thử nghiệm với cả hai đầu vào đều rỗng
    double result = Analyzer.calculate("", "");
    Assert::IsTrue(result == 0.0);
    
    // Thử nghiệm với một bên rỗng
    double ratio2 = Analyzer.calculate("Nội dung duy nhất", "");
    Assert::IsTrue(ratio2 == 0.0);
}

2. Đối Chiếu Đoạn Văn Giống Nhau

TEST_CASE(Test_Identical_Text_Scores) {
    string txtA = "Hệ thống hoạt động tốt";
    string txtB = "Hệ thống hoạt động tốt";
    
    double score = Analyzer.compare(txtA, txtB);
    Assert::AreEqual(1.0, score, 1e-5, "Văn bản hoàn toàn giống nhau phải có điểm 1.0");
}

3. Xử Lý Sự Thay Đổi Từ Ngữ (Paraphrasing)

TEST_CASE(Test_Paraphrased_Content) {
    // Thay đổi một số từ nhưng ý nghĩa giữ nguyên
    string orig = "Tôi đi xe buýt đến trường";
    string mod = "Tôi dùng xe buýt đến trường"; 
    
    double similarity = Analyzer.compare(orig, mod);
    
    // Kết quả phải nằm trong khoảng 0.4 đến 0.9 do có thay đổi ký tự
    Assert::IsTrue(similarity >= 0.4 && similarity <= 0.9);
}

4. Xử Lý File Lớn Không Bị Crashes

TEST_CASE(Test_Long_File_Stability) {
    // Tạo chuỗi giả kích thước lớn
    string bigText(50000, 'X');
    string sameText(50000, 'X');
    
    auto start = high_resolution_clock::now();
    double val = Analyzer.compare(bigText, sameText);
    auto stop = high_resolution_clock::now();
    
    Assert::IsTrue(val > 0.9); // Phải rất cao vì giống hệt
    // Không được gây lỗi OutOfMemoryException
}

Quy Trình Quản Lý Mã Nguồn Với Git

Toàn bộ vòng đời phát triển được giám sát qua nền tảng GitHub để đảm bảo tính đồng bộ và ổn định:

  1. Tạo Branch: Mỗi tính năng mới bắt buộc tạo nhánh riêng (ví dụ: feature/lcs-optimization) từ nhánh chính main.
  2. Commit & Push: Cập nhật thông tin commit tuân thủ chuẩn mực, ngắn gọn và chứa hướng dẫn thay đổi.
  3. Pull Request: Sau khi hoàn thành và test trên máy chủ, nộp yêu cầu gộp mã (PR) để đội ngũ rà soát lỗi.
  4. Merge: Khi xung đột được giải quyết, mã sẽ được hợp nhất vào nhánh gốc.
  5. Release: Các tệp tin nhị phân và mã nguồn cuối cùng được đóng gói và tải lên mục Releases.

Thẻ: C++ Thuật Toán LCS Phát Hiện Đạo Văn quy hoạch động Unit Test

Đăng vào ngày 14 tháng 6 lúc 07:52