当我尝试使用Huffman代码对以下流进行编码时遇到了一些问题。 如果编码系统是
A:0 B:10 C:110 D:111
然后序列ABBADC将是010100111110。 我收到它时如何解码这个比特流? 编码系统是否必要? 如果是这样,我该如何发送此表? 如果没有,我应该如何解码它们?
答案 0 :(得分:1)
你必须建一棵树
Start
/0 \1
| /0 \1
A | / \
B | |
C D
按照二进制数字的每一步移动它。每次找到叶子 - 返回根
您应该将此表格发送到文件的特殊标题部分或完全单独发送
答案 1 :(得分:1)
您不需要发送表,只需要发送位长度。即,1,2,3,3。给定比特长度,可以在编码和解码两端以相同的方式构造规范前缀码。有关规范代码的详情,请参阅this answer。
解码前缀代码的方法有很多种。你可以一点一点地走,好像你正在穿越一棵树,最终到达一个象征的叶子。然后从树的根开始返回下一位。
对于规范代码,其中确保较短的长度具有比较长的长度更低的整数值,将比特收集为整数并与每个长度的值表进行比较。一旦建立了长度,整数就会对符号表进行索引。这就是示例代码puff.c所做的。
最快的方法之一是拥有一个表,其长度包含最长的代码,其中每个表条目是符号和位数。具有较少位的代码具有多个表条目。在这种情况下:
000: A 1
001: A 1
010: A 1
011: A 1
100: B 2
101: B 2
110: C 3
111: D 3
然后你读取三位,查找它,在表中发出符号,并消耗指示的位数。然后根据需要获得更多位以返回三位并重复。如果到达输入的末尾,只需填充零位,但要注意多少。如果解码的代码使用填充位,则标记错误。
这是zlib's inflate代码所做的事情,虽然它builds a two-level table稍微复杂一点,因此不会花太多时间来构建长表。
答案 2 :(得分:0)
传统上,树数据结构用于存储霍夫曼数据。因此,当您处理A,B,C,D时,您将继续构建二叉树。编码的值,即A,B,C,D存储在叶子上。 当您收到位流时,您只需遍历已经拥有的树来解码代码。
在你的情况下,如果你只有这4个输入,那么我建议使用一个比树更多的散列图,因为它会让你的查找更容易。