我有一个二进制文件,我知道其中每个符号的出现次数。我需要预测压缩文件的长度IF我是使用Huffman算法压缩它。我只对假设的输出长度感兴趣而不是对单个符号的代码感兴趣,因此构建霍夫曼树似乎是多余的。
作为一个例子,我需要得到像"二进制字符串38位,包含4个a,5 b和10 c可以压缩到28位。",除了文件和字母大小都要大得多。
基本问题是:可以在不构建树的情况下完成吗?
看看贪婪的算法:http://www.siggraph.org/education/materials/HyperGraph/video/mpeg/mpegfaq/huffman_tutorial.html 似乎树可以在n * log(n)时间内构建,其中n是文件中不同符号的数量。这不是渐渐的坏,但是需要为树节点分配内存,并且在我的情况下做了很多工作。
答案 0 :(得分:2)
压缩文件中每个符号的平均位数的下限只是输入中所有符号x的熵H = -sum(p(x)*log(p(x)))
。 P(x) = freq(x)/(filesize)
。使用此compressed length(lower bound) = filesize*H
。这是压缩文件大小的下限。但遗憾的是,在大多数情况下,最佳熵是不可实现的,因为比特是整数而不是分数,因此在实际情况下需要构造霍夫曼树以获得正确的压缩大小。但是,可以使用最佳压缩大小来获得可能的压缩量的上限,并决定是否使用霍夫曼。
答案 1 :(得分:1)
您可以在霍夫曼编码中对每个符号的平均位数进行上限 H(p1,p2,...,pn)+ 1 其中 H 是熵,每个 pi 是符号 i的概率在输入中出现。如果将此值乘以输入大小 N ,它将为您提供近似编码输出的长度。
答案 2 :(得分:1)
您可以轻松修改算法以在数组中构建二叉树。根节点位于索引0,其左节点位于索引1,右节点位于索引2.通常,节点的子节点位于(index*2) + 1
和(index * 2) + 2
。当然,这仍然需要内存分配,但是如果你知道你有多少个符号,你可以计算树中有多少个节点。所以这是一个单一的数组分配。
我不知道所做的工作真正浪费在哪里。您必须以某种方式跟踪组合逻辑 ,并且如图所示在树中执行它非常简单。我知道你只是在寻找最终的答案 - 每个符号的长度 - 但如果不做这项工作你就无法得到答案。