使用可变长度符号的霍夫曼编码



我正在考虑使用霍夫曼代码来压缩文本,但使用可变长度的符号(字符串)。例如(使用下划线作为空格):

huffman-code | symbol
------------------------------------
00           | _
01           | E
100          | THE
101          | A
1100         | UP
1101         | DOWN
11100        | .
11101        |
1111...
(etc...)

如何构建频率表?显然存在一些重叠的问题,序列_TH的出现频率与THE几乎一样,但在表中是无用的(_THE都有短的huffman码)。

这样的算法存在吗?它有一个特别的名字吗?生成频率表的技巧是什么?我需要标记输入吗?我在垃圾箱/网上什么也没找到。(所有这些都让我想起了根树)。

我在考虑使用一个迭代过程:

  1. 为长度为1到N的所有符号生成一个霍夫曼树
  2. 从树中删除所有N>1且低于特定计数阈值的符号
  3. 重新生成第二个huffman树,但这次用前一个来标记输入(可能使用基数树进行查找)
  4. 重复到1,直到我们收敛(或收敛几次)

但我不知道如何防止重叠(_THTHE)的问题。

只要正确地标记文本,就不必担心重叠问题。您可以将每个标记定义为单词(最长的连续字符流)、标点符号或空白字符("、"\t"、"n")。因此,根据定义,令牌/符号不重叠。

但是直接使用霍夫曼编码并不适合压缩文本,因为它不能利用符号之间的依赖关系。例如,"q"后面可能跟有"u","qu"后面可能跟着元音,"谢谢"后面可能后跟"你"等等。你可能想研究像"LZ"这样的高阶编码器,它可以通过将数据转换为查找地址、复制长度和偏离符号的序列来利用这种冗余。下面是LZ如何工作的一个例子。然后,您可以对三个流中的每一个应用霍夫曼编码来进一步压缩数据。DEFLATE算法就是这样工作的。

这不是一个完整的解决方案。

由于您必须同时存储序列和查找表,也许您可以贪婪地选择将存储成本降至最低的符号。

步骤1:存储长度最多为k的所有符号,并跟踪它们的计数

步骤2:对于每个可能的符号,计算节省的空间(或压缩比)。

Encode_length(符号)=log(N)-log(计数(符号))

Space_saved(symbol)=长度(symbol)*计数(symbol)-编码长度(symbol

N是所有符号的总频率(我们还不知道,可能是近似值?)。

步骤3:选择最佳符号,并减去与之重叠的其他符号的频率。

步骤4:如果整个序列尚未编码,则选择下一个最佳符号(即,转到步骤2)

注意:这只是一个大纲,它既不完整,也不具有计算效率。如果你正在寻找一个实用的快速解决方案,你应该使用krjampani的解决方案。这个答案纯粹是学术性的。

相关内容

  • 没有找到相关文章

最新更新