霍夫曼码压缩

Huffman Code Compression

本文关键字:压缩 霍夫曼      更新时间:2023-10-16

我正在做一个关于霍夫曼编码的作业。我已经成功地从文本文件中构建了字符的频率树,为每个字母生成0和1的代码,使用代码将文本文件写入另一个文件,并解码代码的句子。

我的目标是实现以下目标:

压缩:将0和1的字符串分解成8位块,并写入该字符由每个块表示到压缩文件。解码的方法是将每个字符替换为表示它所需的8位。

我很不确定我是如何把它压缩成8位块的。

您必须跟踪两种状态:您为每个字符写入的位,其数量将根据字符在树中的级别和您写入的8位块而变化。您需要在位级别上修改输出块。

有多种方法。这里有一个解决方案,通过移动一个数据位并附加该位来写入,每次写入一个位。当数据位满时,它被写入8位块输出接收器。下面的代码用一个哨兵位检查数据位溢出,最终被移出8位范围:

static unsigned int out = 0x01;
void write_bit(bool bit)
{
    out <<= 1;                    // shift byte to make room
    if (bit) out |= 0x01;         // set lowest bit id desired
    if (out & 0x100) {            // was the sentinel bit shifted out?
        write_byte(out & 0xff);   // final output of 8-bit chunk
        out = 0x01;               // reset to sentinel vylue
    }
}
void flush_bit()
{
    while (out != 0x01) write_bit(false); 
}
int main()
{
    write_bit(1);
    write_bit(0);
    write_bit(1);
    // ...
    flush_bit();
    return 0;    
}

flush()确保仍然在数据字节中的位通过用零位填充霍夫曼序列来写入。

实际的位输出是这样的:

  0000 0001    // initial state: one sentinel bit
  0000 0011    // after writing a 1
  0000 0110    // after writing a 0
  1101 1111    // after writing five more 1s
1 1011 1110    // after writing a 0: data byte is full
               // write 1011 1110 to final output
  0000 0001    // reset data byte

要实现这一点,数据位必须存储在一个整数中,该整数可以容纳比字节更多的位。

您还可以使用一个单独的变量来跟踪字节状态。一个一个地写比特可能效率不高,但很简单。