我编写了一个程序将一篇文章编码为霍夫曼代码并输出一个代码表。
时:000 日:1011 电子:100 左:11 时:01 回复:1010 字:001 总位数:27 编码代码:000100111101001011010111011
我想编写一个程序,将文件作为输入并对其进行解码。
但我不知道如何重建它。
我的问题是如何重建哈夫曼树?
如果代码是以规范方式构建的,则不需要重建霍夫曼树,这使得较短的代码在数值上比较长的代码小。有很多方法可以将 0 和 1 任意分配给霍夫曼二叉树的每个分支,并且所有方法都会产生相同的代码最优性。从众多选择中选择一种可以在解码和传送代码方面提供优势。
霍夫曼算法所需的唯一信息是代码长度,即每个符号的位数。这样,您就可以构造一个从较短的代码到较长的代码的规范霍夫曼代码,并在任何给定的代码长度内按词汇顺序对符号进行排序(例如,按 H、e、w 的顺序对所有长度为 3 的代码进行排序)。在代码长度内排序的目的是减少要发送到接收器以重构代码的数据量。
然后你会得到这个替代代码:
l:00
o:01
H:100
e:101
w:110
d:1110
r:1111
Run Code Online (Sandbox Code Playgroud)
现在可以使用两个简单的表来完成解码,其中一个表只是按顺序排列的符号,即“loHewdr”,以及步进到下一个代码长度的代码值。步长为0000从一位到两位、1000三位、1110四位。您读取最长代码的足够位(如果需要,请在末尾附加零,但不要在后续步骤中将它们用作代码的开头)。然后,如果该值小于下一个代码长度的起始值,则使用该值作为表中的索引,同时考虑代码中当前的位数。否则,将值的数量添加到索引的下一个值,然后检查下一步。计算跳过的值的数量还需要跟踪当前步骤中代码中的位数。
一旦你解码了一个符号,你就知道它有多少位。从流中删除这些位并重复。
这种方法还具有对于最常见的最短代码来说速度最快的优点。由此产生的解码速度非常好。(还有其他更快的表驱动方法,但它们要复杂得多。)