Bài tập & Hướng dẫn Các giải thuật nén file docx

5 508 4
Bài tập & Hướng dẫn Các giải thuật nén file docx

Đang tải... (xem toàn văn)

Thông tin tài liệu

1 / 5 CTDL 2 CÁC GIẢI THUẬT NÉN oOo Bài 1. Nén RLE Viết lớp RLE với các chức năng cơ bản để nén và giải nén tập tin, sử dụng thuật toán nén PCX RLE. Các chức năng yêu cầu như sau: - Contructor: khởi tạo các thành phần dữ liệu cần thiết cho việc nén và giải nén - Compress: tiến hành nén 1 file cho trước thành 1 tập tin nén. Tham số truyền vào là tên của file cần nén và tên file kết quả nén. Kết quả trả về 0 nếu không thành công; 1 nếu thành công, trong trường hợp này, trả về hiệu suất của phép nén. - De-Compress: giải nén 1 file cho trước (đã được nén bằng chức năng Compress của class). Tham số truyền vào là tên của file nén và tên file kết quả giải nén. Kết quả trả về 0 nếu không thành công; 1 nếu thành công. - Destructor: giải phóng các dữ liệu Yêu cầu: thư viện được xây dựng thành 2 file - File .H chứa mô tả class - File .CPP chứa cài đặt các phương thức của class Bài 3. Nén Huffman tĩnh Viết lớp STATIC_HUFFMAN với các chức năng cơ bản để nén và giải nén tập tin. Các chức năng yêu cầu như sau: - Contructor: khởi tạo các thành phần dữ liệu cần thiết cho việc nén và giải nén - Compress: tiến hành nén 1 file cho trước thành 1 tập tin nén. Tham số truyền vào là tên của file cần nén và tên file kết quả nén. Kết quả trả về 0 nếu không thành công; 1 nếu thành công, trong trường hợp này, trả về hiệu suất của phép nén. File nén lưu bảng thống kê số lần xuất hiện của các ký tự với mô tả chi tiết Header như sau: o 4 bytes: số byte (kích thước) của file gốc o 2 bytes: chiều dài Header (kể cả bảng thống kê số lần xuất hiện của các ký tự) = 6 + 5*n o Bảng thống kê số lần xuất hiện của mỗi ký tự (5*n bytes) - De-Compress: giải nén 1 file cho trước (đã được nén bằng chức năng Compress của class). Tham số truyền vào là tên của file nén và tên file kết quả giải nén. Kết quả trả về 0 nếu không thành công; 1 nếu thành công. - Print-Tree: in cây Huffman - Print-Code-Table: In bảng mã bit của từng ký tự. Theo thứ tự tăng dần của mã ASCII - Destructor: giải phóng các dữ liệu 2 / 5 Hướng dẫn tóm tắt ý chính Bài 3: Mô tả cây Huffman: #define MAX_TREE_NODES 511 // số nút max trong cây #define MAX_CODETABLE_ITEMS 256 // số phần tử max trong bảng mã bit #define MAX_BIT_LEN 256 // c.dài max của mã bit 256 bits # 32 bytes // Cấu tạo 1 phần tử trong cây struct HUFF_TREE_NODE { char c; // Ký tự đại diện Node unsigned long nFreq; // Trọng số của node char nUsed; // 1: Đã xử lý – 0: Chưa xử lý (dùng lúc tạo cây) int nLeft, nRight; // Con trỏ nút con trái, phải (-1 nếu không có nút con) } // Cấu tạo 1 phần tử trong bảng mã bit struct CODE_TABLE_ITEM { char Bits[MAX_BIT_LEN/8]; // Mã bit của ký tự unsigned char nBitLen; // số bit thật sự sử dụng } // Mảng lưu trữ cây struct HUFF_TREE_NODE HuffTree[MAX_TREE_NODES]; // Bảng mã bit của các ký tự. Mã bit của ký tự a là HuffCodeTable[a] struct CODE_TABLE_ITEM HuffCodeTable[MAX_CODETABLE_ITEMS]; // Các hàm chính quan trọng void initTree(); void initCodeTable(); int demKytu(char *fn); int tim2PhantuMin(int &i, int &j); int taoCay(); void taoBangMaBit(int nRoot); void duyetCay(int nCurrNode, char *BitCode, int BitCodeLen); int maHoa1KyTu(char c, FILE *f, int nFinish=0); // // Hàm initTree(…) // + Khởi tạo cây (HuffTree), 511 phần tử. Trong đó, 256 phần tử đầu tiên là 256 nút lá của cây. // Phần tử thứ i: // - c = ký tự thứ i (dùng cho 256 phần tử đầu tiên) // - nFreq = 0; nUsed = 0; (dùng cho 511 phần tử) // - nLeft = nRight = -1; (dùng cho 511 phần tử) // void initTree() { … } 3 / 5 // // Hàm initCodeTable(…) // + Khởi tạo bảng mã bit (HuffCodeTable) 256 phần tử // - nBitLen = 0 // void initCodeTable() { … } // // Hàm demKytu(…) // + Duyệt file fn, đếm số ký tự mỗi loại và cập nhật vào bảng thống kê // (256 phần tử đầu tiên của cây) // + Hàm trả về số loại ký tự trong file // int demKytu(char *fn) { … } // // Hàm taoCay(…) // + Dựa trêh bảng thống kê (256 phần tử đầu tiên của cây), tạo các nút mới // + Thêm các nút mới vào cuối mảng HuffTree (từ phần từ 257  511) // + Hàm trả về chỉ số của phần tử chứa nút gốc của cây // int taoCay() { int n = 256; // Nút mới bắt đầu từ phần tử thứ 257 trong mảng while (1) { Kq = tim2PhantuMin(i, j); // Tìm 2 phần tử có trọng số nhỏ nhất // phần tử i nhỏ hơn phần tử j if (Kq==0) break; // Không tìm thấy  đã tạo cây xong, // nút gốc nằm tại vị trí (n-1) // Nếu tìm được 2 phần tử nhỏ nhất (i, j)  tạo 1 phần tử mới với 2 con là i, j …. n++; // Đánh dấu 2 phần tử i, j đã xử lý xong …. } return (n – 1); } // // Hàm tim2PhantuMin(…) // + Tìm 2 phần tử có trọng số nhỏ nhất trong bảng (chỉ xét trên những phần tử chưa xử lý) // (có cờ nUsed = 0 và nFreq > 0) // + Hàm trả về 0 nếu không tìm được 2 phần tử (chỉ còn 1 phần tử duy nhất) //  đã xây dựng cây xong // + Hàm trả về 1 nếu tìm được 2 phần tử. Lúc đó, i và j là chỉ số của 2 phần tử tìm được. 4 / 5 // - Qui ước phần tử i luôn nhỏ hơn phần tử j (nhỏ hơn về trọng số; // nếu trọng số bằng nhau, nhỏ hơn về mã ASCII) //  phần tử i sẽ trở thành nút con bên trái; phần tử j sẽ trở thành nút con bên phải // int tim2PhantuMin(int &i, int &j) { } // // Hàm taoBangMaBit(…) // + Duyệt cây HuffTree và xác định bảng mã bit cho mỗi ký tự. // + Kết quả lưu vào bảng HuffCodeTable // + nRoot là chỉ số của phần tử gốc trong cây (trả về từ hàm taoCay) // + Gọi hàm duyetCay với nút đầu tiên được xét là nút gốc // void taoBangMaBit(int nRoot) { … } // // Hàm duyetCay(…) // + Hàm đệ qui duyệt cây Huffman (HuffTree) và tạo lập bảng mã bit cho các ký tự // + nCurrNode: chỉ số của nút hiện đang được duyệt // + BitCode: chuỗi bit được ghi nhận hiện tại (ứng với nút nCurrNode) // + BitCodeLen: chiều dài dãy bit (số bit thực sự trong dãy BitCode) // void duyetCay(int nCurrNode, char *BitCode, int BitCodeLen) { if (nCurrNode==-1) return; if (Nếu nút hiện tại là nút lá) { // thì thêm mã bit của nó vào bảng HuffCodeTable … return; } // Thêm 1 bit 0 vào dãy BitCode, tại vị trí BitCodeLen … duyetCay(HuffTree[nCurrNode].nLeft, BitCode, BitCodeLen+1); // Duyệt trái // Thêm 1 bit 1 vào dãy BitCode, tại vị trí BitCodeLen … duyetCay(HuffTree[nCurrNode].nRight, BitCode, BitCodeLen+1); // Duyệt phải } // // Hàm maHoa1KyTu(…) // + Hàm mã hóa 1 ký tự c thành chuỗi bit tương ứng và ghi vào file f // + c: ký tự cần mã hóa // + f: file output để ghi chuỗi bit được mã hóa // + finish: cờ cho biết có kết thúc quá trình mã hóa hay không (khi finish=1, quá trình kết thúc, // hàm sẽ ghi các bit dư vào file f, lúc này không cần quan tâm ký tự c). Khi đó, hàm trả về // số bit có ý nghĩa đã ghi lên file. // 5 / 5 int maHoa1KyTu(char c, FILE *f, int nFinish=0) { // dựa vào HuffCodeTable, xác định được chuỗi bit của ký tự c static char out = 0; // byte sẽ được ghi trực tiếp lên file f. Khai static để lần gọi sau có // thể giữ được những bit thừa của lần gọi trước static char SoBit = 0; // số bit đang thực sự được lưu trong byte out // Nếu finish = 1 và SoBit > 0 (lúc này byte out lưu những bit thừa) thì ghi byte out vào file // f và thoát khỏi hàm, trả về SoBit // Duyệt qua từng bit trong chuỗi bit mã hóa, với mỗi bit: // +Thêm bit vào byte out // +Nếu byte out đủ 8 bit, ghi byte out vào file f và đặt lại out=0, SoBit=0 // Lưu ý: các bit cao được lấy trước, bit thấp được lấy sau } Một số thao tác xử lý bit : //lay bit thu j cua N BIT = (N >> j) & 1; //Gan 1 bit 0 vao BitCode tai vi tri j temp = 1 << j; //bat bit thu j cua temp len 1 temp != temp; //phu dinh de bit thu j cua temp la 0, cac bit khac la 1 BitCode &= temp; //cho BitCode AND voi temp de tat bit j //Gan 1 bit 1 vao BitCode tai vi tri j temp = 1 << j; //bat bit thu j cua temp len 1 BitCode[i] |= temp; //cho BitCode OR voi temp de bat bit j . 1 / 5 CTDL 2 CÁC GIẢI THUẬT NÉN oOo Bài 1. Nén RLE Viết lớp RLE với các chức năng cơ bản để nén và giải nén tập tin, sử dụng thuật toán nén PCX RLE. Các chức năng yêu cầu như. tạo các thành phần dữ liệu cần thiết cho việc nén và giải nén - Compress: tiến hành nén 1 file cho trước thành 1 tập tin nén. Tham số truyền vào là tên của file cần nén và tên file kết quả nén. . với các chức năng cơ bản để nén và giải nén tập tin. Các chức năng yêu cầu như sau: - Contructor: khởi tạo các thành phần dữ liệu cần thiết cho việc nén và giải nén - Compress: tiến hành nén

Ngày đăng: 13/07/2014, 22:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan