用C ++紧凑地保存一个霍夫曼树

时间:2015-04-01 16:50:39

标签: c++ huffman-code

让我们说我用压缩文件编写了我的霍夫曼树。所以我有一个例子文件输出:

001A1C01E01B1D

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

希望我已经足够清楚了。

2 个答案:

答案 0 :(得分:1)

只需将 n 字节序列视为 8n 位的序列。使用>><<|&运算符汇总可变长度位代码序列中的字节。

流的结尾对于正确处理非常重要。您需要一个流代码结束,以便解码器知道停止,而不是尝试解码完成最后一个字节的最后填充位。

答案 1 :(得分:1)

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

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

一级上升,首先假设填充位的数量适合3位。定义编码文件的最后3位以编码填充位的数量。现在,如果消息占用最后一个字节的不超过5位,则填充可以很好地适合同一个字节。如果需要添加一个字节来包含填充,则最大间隙为5 + 2 = 7(来自额外字节的未使用高位的5,而2是最后一个字节中可用的最大空间,否则为3位填充值将适合那里。由于0-7可以用3位表示,因此可以工作(它不适用于2位,因为最大间隙更大,可表示值的范围更小)。

顺便说一句,将填充信息放在文件末尾(而不是文件开头的标题)的主要优点之一是压缩函数可以在流上运行而不必提前知道它的长度。通过仔细处理EOF信号,解压缩也可以是基于流的。