【问题标题】:Huffman Code Compression霍夫曼代码压缩
【发布时间】:2014-03-23 02:30:15
【问题描述】:

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

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

压缩:将 0 和 1 的字符串分成 8 位块,并写入字符 由压缩文件的每个块表示。 通过将每个字符替换为表示它所需的 8 位来进行解码。

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

【问题讨论】:

  • 你一次取八位,并将它们转换成一个从 0 到 255 的数字。这就是你要写的字符。所以 00010000 = 32 十进制 = ' '(一个空格)。到目前为止,您尝试过什么?
  • 将 0 和 1 视为位。
  • 如果一个字母的代码跨多个块运行会发生什么?
  • 我只想链​​接到我以前的答案:stackoverflow.com/a/17929178/555045 简而言之,永远不要使用字符串。

标签: c++ algorithm compression huffman-code


【解决方案1】:

您必须跟踪两种状态:您为每个字符写入的位,其数量将根据树中字符的级别和您写入的 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

为此,数据位必须存储在一个整数中,该整数可以容纳比一个字节更多的位。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多