假设我已经用压缩文件对霍夫曼树进行了编码。因此,我有一个示例文件输出:

001A1C01E01B1D

我在将此字符串逐位保存到文件时遇到问题。我知道C++一次只能输出到一个字节的文件,因此在将这个字符串存储为字节时遇到了问题。是否可以将前三位转换为一个char而不将程序填充到一个字节?如果它为遍历代码填充一个字节,那么我的树(和代码)将被完全弄乱。如果我一次将其切成一个字节,那么如果树不是8的倍数又会怎样呢?如果压缩文件的位长不是8的整数倍,会发生什么?

希望我已经足够清楚了。

最佳答案

解决此问题的标准方法是填充。有许多可能的填充方案。填充方案最多填充偶数个字节(即8位的倍数)。另外,它们对消息的长度进行编码(以位为单位),或者对填充位数进行编码(从中可以通过减法来确定消息的长度)。后一种解决方案显然会导致填充效率更高。

最简单的是,您可以在最后一个字节中附加“未使用”的位数作为附加字节值。

从上一层开始,假设填充位的数量适合3位。定义编码文件的最后3位以对填充位的数量进行编码。现在,如果消息占用的最后一个字节不超过5位,则填充可以很好地适契约(Contract)一字节。如果需要添加一个字节来包含填充,则最大间隙为5 + 2 = 7(5来自额外字节的未使用高位,而2是最后一个字节中的最大可用空间,否则为3 -bit填充值就适合在那里)。由于0-7可以用3位表示,因此可以工作(对于2位无效,因为最大间隙较大并且可表示值的范围较小)。

顺便说一句,将填充信息放置在文件末尾(而不是作为文件头放在文件头)的主要优点之一是,压缩函数可以随后对流进行操作而不必知道其长度提前。通过仔细处理EOF信号,解压缩也可以基于流。

关于c++ - 用C++紧凑地保存霍夫曼树,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29396435/

10-11 17:21