【问题标题】:Huffman tree for big files大文件的霍夫曼树
【发布时间】:2017-01-24 11:49:54
【问题描述】:

我一直在互联网上搜索,但找不到我需要的东西。

我必须使用 Huffman 编码压缩大文件。我的想法是读取文件的前 1-2MB

(避免先读取整个文件来构建树,然后再读取一次以对其进行编码,避免 O(2n) ),

并构建霍夫曼树。如果缺少 256 个字母字节中的任何一个,我会自己添加它,以防它稍后出现在文件中(而不是前 1-2 MB)。 但是尝试使用这个来测试结果:

int * totalFr = new int[256];
unsigned char * symArr= new  unsigned char[256];

for (int i = 0; i < 256; i++)
{
    totalFr[i] = i;
    symArr[i] = unsigned char(i);
}

int size = sizeof(symArr) / sizeof(symArr[0]);
buildHuffmanTree(totalFr,symArr, size );
delete[] totalFr;
delete[] arrei;

buildHuffmanTree 是一个函数,它构建 Huffman 树,让我意识到我能得到的最佳字符代码是 7 位,例如 0000001

这就是我的问题的来源 - 为完整的 256 个单词字母表构建 Huffman Tree 是否值得?还是对像 1-2MB 这样的块使用自适应霍夫曼编码更好

【问题讨论】:

  • delete[] 不是 C。要么您的标签错误,要么您将遇到编译问题
  • 我在 C++ 上做。我将其标记为C,因为我认为它很相似,人们宁愿告诉我使用std::vector,然后实际回答我有关算法问题的问题。我现在将其取消标记:)
  • 完全取决于文件数据。如果文件其余部分中的数据与开头“足够接近”,那么您的想法有效。如果没有,那么您必须为每个部分制作不同的表格。在几个文件上尝试两种方式。

标签: c++ tree huffman-code


【解决方案1】:

除非数据在存在哪些字节方面存在极大偏差,否则您不能仅对霍夫曼编码抱有太多期望。我刚刚尝试了来自 Wikipedia 的 100 MB 英文文本文件。它将文件缩小到其原始大小的 63%,因此平均可能是 8 位到 5 位。这也是一次以大约 16 KB 的块执行 Huffman,以便代码适应每个块。

正常的 zlib 压缩也会寻找匹配的字符串,将其缩小到原始大小的 35%。更高级的压缩器,例如 xz,它会花费更多的时间和内存来寻找更远更远的距离来匹配字符串,并且比 Huffman 编码做得更好,将其缩小到原始大小的 26%。

【讨论】:

  • 我担心如果用完整的 256 字集大小进行霍夫曼编码会超过原始数据大小?树适应每个 16 KB 块是什么意思?您进行正常的 Huffman 编码并将其用于 16 KB 块,或者您使用了adaptive Huffman(为什么要每 16 KB 更新它,而不是每 1 个字符)?在此先感谢:)
  • 是的,添加不出现的符号可能会导致对其他可压缩数据进行扩展而不是压缩。相反,您应该做 zlib 所做的事情,即为每个数据块创建一个新的 Huffman 代码。计算新代码所需的时间和发送代码描述所需的位数对于足够大的块来说可能是足够小的分数。
  • 可以,但您不需要发送树。您只需要发送本身可以压缩的长度,并使用规范代码。
  • 您只需要每个符号的位数,您就可以在两端构造相同的霍夫曼码。你可以阅读the article on Wikipedia
  • 您可以查看puff.c 以获得简单规范代码解码器的示例。 decode() 获取每个码长的符号个数列表,以及对应符号的列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多