Mã hóa Huffman: tại sao không cần dải phân cách?


17
Char        Code
====        ====
E           0000
i           0001
y           0010
l           0011
k           0100
.           0101
space       011
e           10
r           1100
s           1101
n           1110
a           1111

Văn bản gốc:

Mắt kỳ lạ nhìn gần hồ

Được mã hóa:
0000101100000110011100010101101101001111101011111100011001111110100100101

Tại sao không cần có dấu phân tách trong mã hóa Huffman?


1
Bởi vì khi bạn giải mã một giá trị nhị phân, bạn lấy đoạn bit "trái sang phải", tùy theo giá trị nào khớp với giá trị từ văn bản gốc. Giống như trong trường hợp này, bạn thấy đoạn mã ngoài cùng bên trái (0000) khớp với E. Nếu có bất kỳ ký hiệu nào có giá trị 000 trong mã char của bạn, bạn sẽ thay thế 000 bằng ký hiệu đó, sau đó bắt đầu tìm kiếm lại từ các bit còn lại trong một cách "trái sang phải". Đó là lý do tại sao bạn không cần bất kỳ sự tách biệt.
Syed Ali Hamza

1
Câu hỏi ngụ ý rằng các dải phân cách thường là cần thiết. Bạn đã biết rằng bạn không cần dấu phân cách Eerie eyes seen near lake(tốt, ngoại trừ ký tự khoảng trắng). Nhưng bản thân các nhân vật không cần dải phân cách. Tại sao không phải vậy?
MSalters

cố gắng tự giải mã nó, không bao giờ có bất kỳ sự mơ hồ nào.
njzk2

@MSalters: Nhưng tách được thường cần thiết với các từ chiều dài thay đổi: cat cheat for micecatch eat form ice. Sự tương tự của bạn là thiếu sót: mỗi chữ cái là nguyên tử; các chữ cái được phân biệt tầm thường và tách biệt nội tại. Một sự tương tự tốt hơn sẽ là "Tại sao bạn có thể đọc kịch bản chữ thảo (viết tay), khi mỗi từ chỉ là một dòng dài, nguệch ngoạc, tự giao nhau?", Và thậm chí đó là một từ tương tự kém, vì bạn có thể nhìn vào một từ viết tay (vì bạn có thể nhìn vào một từ viết tay ( hoặc thậm chí là một phần của một) và phân biệt các chữ cái riêng lẻ - trong khi đó một chuỗi được mã hóa Huffman là vô nghĩa nếu bạn không thể nhìn thấy từ đầu.
G-Man nói 'Phục hồi Monica'

@MSalters Tôi không thấy điểm yout. Tôi không cần dấu phân cách cho các ký tự vì chúng tôi đang sử dụng mã hóa có độ rộng cố định: mỗi khối tám bit liên tiếp tương ứng với một ký tự. Nhưng mã hóa Huffman không phải là chiều rộng cố định, do đó, câu hỏi.
David Richerby

Câu trả lời:


50

Bạn không cần một dấu phân cách vì mã Huffman là mã không có tiền tố (cũng không có ích, được gọi là "mã tiền tố"). Điều này có nghĩa là không có từ mã nào là tiền tố của bất kỳ loại tiền mã hóa nào khác. Ví dụ, từ mã cho "e" trong ví dụ của bạn là 10 và bạn có thể thấy rằng không có từ mã nào khác bắt đầu bằng các chữ số 10.

Điều này có nghĩa là bạn có thể giải mã một cách tham lam bằng cách đọc chuỗi được mã hóa từ trái sang phải và xuất ra một ký tự ngay khi bạn nhìn thấy một từ mã. Ví dụ: 0, 00 và 000 không mã hóa bất cứ điều gì để bạn tiếp tục đọc bit. Khi bạn đọc 0000, mã hóa "E" và, vì mã không có tiền tố, bạn biết rằng không có từ mã 0000x nào khác, vì vậy bây giờ bạn có thể xuất "E" và bắt đầu đọc từ mã tiếp theo. Một lần nữa, 1 không mã hóa bất cứ thứ gì ngoài 10 mã hóa "e". Không có từ mã nào khác bắt đầu bằng "10", vì vậy bạn có thể xuất "e". Và như thế.


1
Mã tiền tố cũng thường được gọi là Mã tức thời (xem ví dụ, Các yếu tố của lý thuyết thông tin của Cover & Thomas). Tôi nghĩ thuật ngữ Mã tiền tố xuất hiện thường xuyên hơn nhiều so với mã không có tiền tố.
Batman

3
Một điều đáng nói nữa là để giải mã một chuỗi các mã Huffman được nối, người ta phải đưa ra ranh giới từ mã chính xác để bắt đầu. Nếu một người cố gắng giải mã chuỗi ở một ranh giới từ mã sai, quá trình giải mã sẽ tạo ra một chuỗi các ký hiệu đầu ra sai.
rwong

@rwong: Nếu mã Huffman bắt đầu được đồng bộ hóa không chính xác, nó có thể tiếp tục xuất các ký hiệu sai vô thời hạn, nhưng bất cứ khi nào nó xác định không chính xác độ dài của một ký hiệu, số lượng trạng thái sai có thể sẽ bị giảm.
supercat

@supercat Tôi đoán tôi sẽ diễn đạt nó theo một cách khác: Nếu bộ giải mã Huffman ban đầu được đặt ở một ranh giới từ mã sai và bắt đầu xử lý, có thể có khả năng (có thể bằng 0 hoặc bất cứ điều gì, và có thể phụ thuộc vào cả từ điển và từ điển nội dung dòng bit) rằng nó có thể hạ cánh trên một ranh giới từ mã chính xác bởi sự trùng hợp ngẫu nhiên trong thời gian hữu hạn và khi điều đó xảy ra, nó sẽ tạo ra kết quả giải mã chính xác cho các ký hiệu tiếp theo. Đã có một số nghiên cứu về các thuộc tính (trên từ điển từ mã và trên luồng bit) sẽ đảm bảo việc đồng bộ hóa lại này.
rwong

@rwong: Nếu dữ liệu gốc là ngẫu nhiên với phân phối sao cho các bit của luồng sẽ có xác suất độc lập là một hoặc 0, thì xác suất không đồng bộ hóa nhiều hơn N ký hiệu sẽ phân rã theo cấp số nhân khi tăng N. Dữ liệu thực tế có nhiều khả năng chứa các mẫu có thể ngăn chặn đồng bộ hóa, nhưng trong thực tế, không có khả năng lỗi khi bắt đầu tệp văn bản 100 MB sẽ làm hỏng tất cả 100 MB văn bản.
supercat

13

Thật hữu ích khi tưởng tượng nó như một cái cây. Bạn chỉ đơn giản là đi ngang qua cây cho đến khi bạn nhấn một nút lá, và sau đó khởi động lại từ gốc. Từ thuật toán mã hóa huffman, bạn có thể thấy rằng loại cấu trúc này được tạo ra trong quy trình.

https://en.wikipedia.org/wiki/File:HuffmanCodeAlg.png


6
Khía cạnh quan trọng ở đây là tất cả các từ mã hợp lệ là các lá. Bạn sẽ cần các dấu phân cách nếu bạn cũng có các ký hiệu trên các nút bên trong.
MvG

3

Không có mã nào ngoài E bắt đầu bằng 0000. Không có mã nào khác ngoài i bắt đầu bằng 0001. Và cứ thế. Như một trường hợp cực đoan, không có mã nào khác ngoài e bắt đầu bằng 01. Bạn không có những thứ như E = 0000, space = 000, nơi bạn sẽ không biết phải làm gì nếu tìm thấy ba số không.

Nhìn vào chuỗi được mã hóa của bạn: 0000101100000 ...

Bạn đọc số không đầu tiên. Bạn biết mã là một trong E, i, y, l, k, dấu phẩy hoặc dấu cách. Số 0 tiếp theo có nghĩa là nó không phải là k, dấu phẩy hoặc dấu cách, mà là E, i, y hoặc l. Số 0 tiếp theo có nghĩa là E hoặc i. Số 0 tiếp theo có nghĩa là số E. Khi bạn biết đó là mã nào, bạn biết bạn đã phân tích tất cả các bit cho mã đó.

Sau đó, bạn có 101100000 ... 1 có nghĩa là bạn có e, r, s, n hoặc a. Bit tiếp theo là 0, vì vậy mã là e. Một lần nữa, bạn đã hoàn thành với nhân vật đó.


-2

Chúng tôi không thể sử dụng dấu phân cách trong mã hóa Huffman vì tương đương nhị phân của mỗi chữ cái không khớp với mã tiền tố của bất kỳ chữ cái nào, vì vậy chúng tôi có thể làm mà không cần sử dụng dấu phân cách.


3
Tôi đã không nói điều đó, chỉ khi không có mức độ khó hiểu của nhiều phủ định lồng nhau. (Và, nhân tiện, không phải là chúng ta không thể sử dụng một dải phân cách; chỉ là chúng ta không cần phải làm vậy.)
David Richerby
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.