ĐH KHTN TP HCM / Khoa CNTT Cấu trúc dữ liệu và giải thuật 1 HƯỚNG DẪN THỰC HÀNH NÉN HUFFMAN TĨNH I Mục tiêu Hiểu rõ và cài đặt được thuật toán nén Huffman tĩnh (static Huffman coding) II Qui định nộp[.]
ĐH KHTN TP.HCM / Khoa CNTT HƯỚNG DẪN THỰC HÀNH NÉN HUFFMAN TĨNH I Mục tiêu Hiểu rõ cài đặt thuật toán nén Huffman tĩnh (static Huffman coding) II Qui định nộp - Sinh viên nộp tập tin nén, có tên .zip .rar chứa source code báo cáo chương trình - Sinh viên nộp kèm file báo cáo ghi mức độ hoàn thành cơng việc mình, - - liệu mà test Tất tập lập trình theo command line (tham số dòng lệnh) Kiến trúc thư mục nộp: o MSSV ▪ MSSV_BT1: • Source: chứa file cpp • Header: chứa file h • Test case: chứa file input để test thử • … ▪ MSSV_BT2: … Mơi trường làm việc: Visual Studio 2015 môi trường tương đương Không sử dụng hàm bị lỗ hổng bảo mật gets, … Hạn nộp: xem link Moodle Bài giống hay nộp file rác điểm MÔN HỌC Nội dung Áp dụng mã Huffman tĩnh để nén tập tin nhị phân Ta xem tập tin cần nén tập tin nhị phân khơng có cấu trúc đọc byte tập tin hết dừng Mỗi byte tập tin tương ứng với ký tự bảng mã ASCII nên từ nói đến ký tự c ta hiểu byte c ngược lại Dữ liệu nhập: Tập tin có kích thước nhỏ 500 KB Tham số dịng lệnh: Pha nén: MSSV.exe compress X Y Ví dụ: 151234.exe compress 151234.cpp 151234.out Ý nghĩa: Dùng thuật toán nén Huffman tĩnh để nén tập tin X lưu kết xuống tập tin Y Cấu trúc liệu giải thuật ĐH KHTN TP.HCM / Khoa CNTT Pha giải nén: MSSV.exe uncompress X Y Z Ví dụ: 151234.exe uncompress 151234.out 151234.huf 151234.cpp Ý nghĩa: Giải nén tập tin X nén thuật toán nén Huffman tĩnh, sử dụng thông tin phục vụ cho việc giải nén lưu tập tin Y lưu kết giải nén xuống tập tin Z Lưu ý: Khi thực phần Yêu cầu nâng cao, tham số Y pha giải nén không cần thiết bị loại bỏ Các bước thực Bước Khai báo cấu trúc (nhị phân) Huffman Để biểu diễn nút Huffman, ta khai báo cấu trúc node sau: struct node { unsigned char c; // ký tự nút unsigned int f; // tần số xuất struct node *left, *right; // nút }; Bước Khởi tạo bảng tần số xuất ký tự Ta ghi nhận tần số xuất byte mảng số nguyên không dấu f gồm 256 phần tử tương ứng với 256 ký tự bảng mã ASCII quy ước f[c] tần số xuất ký tự c Mảng f khai báo sau: unsigned int f[256]; Ban đầu tần số xuất tất ký tự nên ta khởi gán giá trị cho tất phần tử f memset(f, 0, sizeof(f)); Bước Đọc tập tin cập nhật bảng tần số Đọc byte tập tin cần nén tăng tần số xuất lên đơn vị Lặp lại thao tác đến hết tập tin dừng Duyệt bảng tần số f, f [i] > (nghĩa byte i có xuất tập tin cần nén) tạo nút Huffman mang ký tự i có tần số f [i] Nút xem gốc nhị phân có nút nút Ta gọi tập nút gốc rừng ký hiệu C Tập C lấy làm đầu vào thuật toán Huffman tổ chức cấu trúc liệu hàng đợi có ưu tiên giải thích bước Cấu trúc liệu giải thuật ĐH KHTN TP.HCM / Khoa CNTT Bước Xây dựng Huffman Ý tưởng Huffman từ rừng có nút (tập C vừa thu bước trên), bước ta gộp hai làm lặp lại rừng Cụ thể, ta lấy hai nút x y có tần số nhỏ nhất, sau tạo nút z, cho z nhận x y làm hai gán giá trị tần số z tổng giá trị tần số x y Lúc này, z trở thành nút gốc thêm vào tập C x y bị loại khỏi C khơng cịn nút gốc Tiếp theo ta lại lấy C hai nút có tần số nhỏ gộp lại theo cách thức vừa nêu Cứ tiếp tục ta xây dựng ngày lớn số rừng giảm bước Do đó, số lần lặp n – với n = |C| số phần tử ban đầu C Nhận xét Tại bước ta ln phải chọn hai gốc có tần số nhỏ Để thực việc ta sử dụng cấu trúc liệu trừu tượng hàng đợi có ưu tiên với độ ưu tiên tần số nhỏ để lưu nút gốc (hay nói cách khác dùng hàng đợi có ưu tiên để tổ chức tập hợp C) Một cấu trúc liệu thuận lợi cho tiêu chuẩn cấu trúc đống (với nút có tần số nhỏ nằm đỉnh đống) Cách cài đặt hiệu thao tác thêm phần tử lấy phần tử có độ ưu tiên cao khỏi hàng đợi tốn chi phí thời gian O(log|C|) Mã nguồn gợi ý: node* huffman(PQueue& Q) { for (int i = 1; i < n; i++) { node *x, *y, *z; z = new node; z->left = x = dequeue(Q); z->right = y = dequeue(Q); z->f = x->f + y->f; insertQUEUE(Q, z); } return z; } Lưu ý: Sinh viên tự cài đặt cấu trúc PQueue sửa lại đoạn mã theo ý Ví dụ minh họa Giả sử chuỗi ký tự nhập chứa ký tự với tần số xuất cho bảng sau: Ký tự Tần số a 10 b Cấu trúc liệu giải thuật c 23 d e 30 f ĐH KHTN TP.HCM / Khoa CNTT Quá trình xây dựng Huffman diễn sau: (i) 10 23 30 f b d a c e 10 23 30 d a c e (ii) f b (iii) 10 12 a 23 30 c e d f (iv) b 22 23 30 c e a d f thuật Cấu trúc liệu giải b ĐH KHTN TP.HCM / Khoa CNTT (v) 30 22 e c a d f b (vi) e c a d Cấu trúc liệu giải thuật f b ĐH KHTN TP.HCM / Khoa CNTT Bước Phát sinh mã Huffman cho ký tự Để lưu mã Huffman cho ký tự, ta dùng mảng ký tự code gồm 256 phần tử ứng với 256 ký tự bảng mã ASCII unsigned char code[256]; Quá trình phát sinh mã Huffman diễn sau: Xuất phát từ nút gốc Huffman, phát sinh bit qua nhánh trái phát sinh bit qua nhánh phải gặp nút Các bit sinh lưu dạng chuỗi ký tự ‘0’ ‘1’ biến tạm tên hufcode Giả sử ký tự nút c hufcode mã Huffman cho c, nghĩa code[c] = hufcode Quá trình lặp lại ký tự nút nhận mã Huffman Ví dụ Huffman minh họa trên, ta thu mã bit ký tự sau: code[‘e’] = ‘0’, code[‘c’] = ‘11’, code[‘a’] = ‘100’, code[‘d’] = ‘1011’, code[‘f’] = ‘10100’, code[‘b’] = ‘10101’ Bước Ghi kết nén xuống tập tin lưu Huffman hỗ trợ cho việc giải nén Đọc lại tập tin cần nén, byte c đọc lên thay mã Huffman tương ứng code[c], code[c] có ký tự đọc byte nối mã Huffman byte code[c], đến chuỗi có ký tự cắt chuyển thành byte (một số có bit) ghi xuống tập tin nén Lưu Huffman vào tập tin output.huf để phục vụ cho việc giải nén Bước Giải nén tập tin Đọc tập tin output.huf để phục hồi lại Huffman Xuất phát từ nút gốc Huffman, đọc bit tập tin nén, bit qua nhánh trái, bit qua nhánh phải, đến nút ghi ký tự nút xuống tập tin Lặp lại thao tác tập tin nén đọc hết, tập tin thu cuối tập tin gốc ban đầu (tập tin trước nén) Yêu cầu nâng cao Tìm phương án lưu trực tiếp Huffman vào tập tin nén thay phải lưu riêng tập tin output.huf để giải nén ta làm việc với tập tin tập tin nén HẾT Cấu trúc liệu giải thuật ... tin nén Lưu Huffman vào tập tin output.huf để phục vụ cho việc giải nén Bước Giải nén tập tin Đọc tập tin output.huf để phục hồi lại Huffman Xuất phát từ nút gốc Huffman, đọc bit tập tin nén, ... kết nén xuống tập tin lưu Huffman hỗ trợ cho việc giải nén Đọc lại tập tin cần nén, byte c đọc lên thay mã Huffman tương ứng code[c], code[c] có ký tự đọc byte nối mã Huffman byte code[c], đến... TP.HCM / Khoa CNTT Pha giải nén: MSSV.exe uncompress X Y Z Ví dụ: 151234.exe uncompress 151234.out 151234.huf 151234.cpp Ý nghĩa: Giải nén tập tin X nén thuật tốn nén Huffman tĩnh, sử dụng thơng