[英]How to save a Huffman table in a file In a way that use the least storage?
這是我在堆棧溢出中的第一個問題。 它很長,但我已經詳細解釋了它,我認為它是可以理解的。
我正在編寫 c++ 的霍夫曼代碼,並將字符和代碼保存在如下表格中:
文字:AAAAAAAAAAAAAAAAAAAABBBBBBBCCCCDDDDEEEE
表:(由霍夫曼樹制作)表
現在,我想以最好的方式將此表保存到文件中。
我不能這樣保存:A1B001C010D001E000
當它變為位時:01000001101000010001010000110100100010000101000101000
因為我無法解碼。
如果我以正常方式保存表格,每個字符都使用 8 位來保存它的代碼。
雖然我的角色有 1 位或 3 位代碼。 (在這種情況下。)
這種方式使用大量存儲空間。
我的想法是添加一個分隔符並為其設置一個代碼。
如果我們添加一個分隔符並制作霍夫曼樹並編寫代碼,就有一個這樣的表。 表2
現在,我們可以用這種方式編寫代碼。
A0SepB110SepC100SepD1111sepE1110sep。
二進制= 0100000101010100001011010101000011100101010001001111101010001011110101
我以這種方式對其進行解碼:
九月 = 101。
rest = 01010100001011010101000011100101010001001111101010001011110101。
rest = 0100001011010101000011100101010001001111101010001011110101。
rest = 11010101000011100101010001001111101010001011110101。
等等...
這種方式仍然使用一點存儲分隔符(字符數 * 分隔符大小)
我的問題:有沒有辦法將第一個表保存在文件中並使用更少的存儲空間?
例如像這樣:A1B001C010D001E000。
不要用代碼保存表格。 只需保存長度。 請參閱規范霍夫曼代碼。
您可以在壓縮數據的開頭將代碼的長度(如 Mark 所說)存儲為 256 字節 header。 每個字節存儲代碼的長度,並且因為您正在使用具有 256 個可能值的字節,並且霍夫曼樹只能具有一定的深度(可能值的數量 - 1),所以您只需要 8 位來存儲代碼.
第一個字節將存儲值 0x00 的代碼長度,第二個字節存儲 0x01 的代碼長度,依此類推。
但是,如果壓縮英文文本,則有更好的存儲表格的方法。 存儲樹的形狀,0 代表節點,1 代表葉子。 然后,在存儲節點和葉子之后,存儲葉子的值。
AAAAAAAAAAAAAAAAAAAABBBBBBBCCCCDDDDEEEE
的樹如下所示:
*
/ \
* A
/ \
* *
/ \ / \
E D C B
所以你可以這樣存儲樹的形狀: 000110111EDCBA
以這種方式存儲霍夫曼代碼更適合壓縮英文文本的原因是存儲樹的形狀需要10n - 1
位(其中n
是您嘗試壓縮的數據中唯一字符的數量)而存儲代碼長度的成本2048
位。 因此,對於小於 205 的唯一字符數,存儲樹的形狀更有效,並且因為普通的英文文本字符串不會包含那么多可能的 256 個 ASCII 字符,所以通常最好存儲樹形。
如果您不只是壓縮文本,而且您正在壓縮更一般的數據,其中唯一字符的數量很可能大於或等於 205,則您可能應該使用代碼長度存儲格式,或者包括header 開頭的 1 位表示是否會有一棵樹或一堆代碼長度,然后根據該位的設置編寫解碼器來解碼其中一個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.