Mã tiền tố (Prefix-Free Binary Code)
Chúng ta vẫn mã hóa các kí hiệu bằng các xâu nhị phân với độ dài không đổi, được gọi là từ
mã của kí hiệu đó. Chẳng hạn bộ mã ASCII, mã hóa cho 256 kí hiệu là biểu diễn nhị phân của
các số từ 0 đến 255, mỗi từ mã gồm 8 bít. Khi mã hóa một tài liệu có thể không sử dụng đến
tất cả 256 kí hiệu, hơn nữa số lần xuất hiện của các ký tự là khác nhau. Do đóta có thể không
cần dùng hết 8 bít để mã hóa cho một ký hiệu, hơn nữa độ dài (số bit) dành cho mỗi kí hiệu có thể khác nhau, kí hiệu nào xuất hiện nhiều lần thì nên dùng ít bít để mã hóa, ký hiệu nào xuất
hiện ít thì dùng nhiều bít để mã hóa. Tuy nhiên, nếu mã hóa với độ dài thay đổi, khi giải mã
ta làm thế nào phân biệt được xâu bít nào là mã hóa của ký hiệu nào. Một trong các giải pháp là dùng các dấu phẩy (",") hoặc một kí hiệu quy ước nào đó để tách từ mã của các kí tự đứng cạnh nhau. Nhưng như thế số các dấu phẩy sẽ chiếm một không gian đáng kể trong bản mã. Một cách giải quyết khác dẫn đến khái niệm mã tiền tố. Mã tiền tố là bộ các từ mã của một tập hợp các kí hiệu sao cho từ mã của mỗi ký hiệu phải không là tiền tố (phần đầu) của từ mã
CHƯƠNG 4: XỬ LÝ SỐ LIỆU TRUYỀN
47
Ví dụ: Giả sử mã hóa từ "ARRAY", ký hiệu cần mã hóa là 3 chữ cái: "A", "R", "Y".
Nếu mã hóa bằng các từ mã có độ dài bằng nhau ta phải dùng ít nhất 2 bit cho một chữ cái chẳng hạn "A"=00, "R"=01, "Y"=10. Khi đó mã hóa của cả từ là 0001010010. Để giải mã ta đọc hai bit một và đối chiếu với bảng mã.
Nếu mã hóa "A"=0, "R"=01, "Y"=11 thì bộ từ mã này không là mã tiền tố vì từ mã của "A" là tiền tố của từ mã của "R". Lúc này để mã hóa cả từ ARRAY phải đặt dấu ngăn cách vào giữa các từ mã 0,01,01,0,11
Nếu mã hóa "A"=0, "R"=10, "Y"=11 thì bộ mã này là mã tiền tố. Với bộ mã tiền tố này khi mã hóa xâu "ARRAY" ta có 01010011.
Biểu diễn mã tiền tố trên cây nhị phân
Nếu có một cây nhị phân n lá ta có thể tạo một bộ mã tiền tố cho n ký hiệu bằng cách đặt mỗi ký hiệu vào một lá. Từ mã của mỗi kí hiệu được được tạo ra khi đi từ gốc tới lá chứa ký hiệu đó, nếu đi qua cạnh trái thì ta thêm số 0, đi qua cạnh phải thì thêm số 1.
Ví dụ: Cây 3 lá sau đây biểu diễn bộ mã của A,R,Y trong ví dụ trên
Mã Huffman:
Là cách xây dựng cây mã tiền tố tối ưu của Huffman (năm 1952) Các bước xây dựng bộ mã Huffman:
Dựng cây từ dưới lên, xuất phát với các nút lá
Các nút lá biểu diễn các ký tự và tần suất xuất hiện của ký tự trong văn bản
Các nút trong có 2 nhánh tương ứng với : 0 là nhánh bên trái và 1 là nhánh bên phải. Các nút này chứa tổng tần suất xuất hiện của các nút trong các nhánh con của nó
Một đường đi từ nút gốc đến nút lá chính là một mã nhị phân biểu diễn ký tự ở nút lá
Ký tự có tần suất lớn sẽ xuất hiện ở mức thấp hơn, ký tự có tần suất nhỏ sẽ xuất hiện ở mức cao hơn trong cây mã Huffman
Ví dụ: cho dãy ký tự cần truyền là: abcdef và tần xuất xuất hiện tương ứng cho trong bảng.
Hãy xây dựng bộ mã Huffman
Dãy ký tự cần mã hóa f e c b d a
CHƯƠNG 4: XỬ LÝ SỐ LIỆU TRUYỀN
48 Dưới đây là các bước xây dựng cây Huffman:
Bộ mã Huffman là: a = 0 b = 101
( duyệt từ gốc) c = 100 d = 111
CHƯƠNG 4: XỬ LÝ SỐ LIỆU TRUYỀN
49
Mã hóa bằng bộ mã Huffman
Các bước mã hóa:
Bước 1: Duyệt văn bản cần mã hóa và xác định tần suất xuất hiện của các ký tự
Bước 2: Sắp xếp các ký tự dựa trên tần suất xuất hiện của chúng trong vănbản
Bước 3: Xây dựng cây mã Huffman dựa trên dãy đã được sắp. Bước 4: Duyệt cây để xác định mã của các ký tự
Bước 5: Duyệt văn bản cần mã hóa và sinh văn bản mã hóa sử dụng mã có được ở bước 4
Ví dụ trên được mã hóa bằng cuỗi nhị phân sau: 010110011111011100
Giải mã Huffman
Xuất phát từ gốc của cây được mã hóa
Đọc lần lượt từng ký tự trong xâu mã hóa từ trái sang Nếu là 0 : đi sang trái
Nếu là 1: đi sang phải
Nếu chạm tới một nút lá ghi ký tự chứa tại nút lá ra, sau đó quay lại nút gốc của cây mã hóa. Ví dụ:
- Lần đọc đầu tiên: 0, sang trái, chạm nút lá a → ký tự a. Rồi quay lại gốc để duyệt tiếp - Lần đọc thứ hai: 1, sang phải, chưa gặp nút lá, 0 sang trái, chưa gặp nút lá, 1 sang phải, gặp nút lá b → ký tự b. Rồi quay lại gốc để duyệt tiếp
- Lần đọc thứ 3: 1, sang phải, chưa gặp nút lá, 0 sang trái, chưa gặp nút lá, 0 sang trái
gặp nút lá là c → ký tự c. Rồi quay lại gốc để duyệt tiếp - Quá trình sẽ dừng khi đã duyệt hết cây.