我的问题是我有100,000多个不同的元素,据我所知,Huffman的工作方式是将最常见的元素分配给0代码,接下来的10代,下一代110,1110,11110等等。我的问题是,如果第n个元素的代码长度为n位,那么一旦我通过了第32个术语,它就像发送32位数据类型一样空间效率更高,例如整数?我在方法论中遗漏了什么吗?
非常感谢您提供的任何帮助。我目前的实施工作是做
code = (code << 1) + 2;
生成每个新代码(看起来是正确的!),但我编码超过100,000个元素的唯一方法是在临时新数据类型中有一个int [],在哪里访问我们要读取的值从int数组作为一个连续的长符号...这不像传输32位int那样节省空间吗?或者更像Huffmans使用前缀代码,并能够明确地确定连续比特流中的每个唯一值?
由于
答案 0 :(得分:2)
你的理解有点偏离 - 看看http://en.wikipedia.org/wiki/Huffman_coding。而且你必须将编码位打包成机器字才能获得压缩 - 霍夫曼编码的数据最好被认为是一个比特流。
答案 1 :(得分:2)
您似乎理解前缀代码的原理。
您能否告诉我们您提到的100,000多种不同元素?
最快的前缀码 - universal codes - 实际上涉及一系列可以预先生成的比特序列,而不考虑实际的符号频率。正如您所提到的,使用这些代码的压缩程序将最频繁的输入符号与最短的位序列相关联,将次最频繁的输入符号与下一个短的位序列相关联,依此类推。
您描述的是一种特殊的前缀代码:unary coding。 一元编码系统的另一种流行变体将频率顺序的元素分配给固定码 “1”,“01”,“001”,“0001”,“00001”,“000001”等
某些压缩程序使用另一种流行的前缀代码:Elias gamma coding。 Elias伽马编码按频率顺序将元素分配给固定的码字集
1
010
011
00100
00101
00110
00111
0001000
0001001
0001010
0001011
0001100
0001101
0001110
0001111
000010000
000010001
000010010
...
第32条Elias伽马码字长约10位,大约是第32个一元码字的一半。 第100,000个Elias伽玛码字长约32位。
如果仔细观察,可以看到每个Elias gamma代码字可以分成两部分 - 第一部分或多或少是您熟悉的一元代码。这个一元代码告诉解码器在其余的特定Elias伽玛码字中跟随多少比特。
还有许多其他类型的前缀代码。 许多人(令人困惑地)将所有前缀代码称为“霍夫曼代码”。
压缩某些特定数据文件时,某些前缀代码在压缩时比其他代码更好。 你如何决定使用哪一个? 哪种前缀代码最适合某些特定数据文件?
霍夫曼算法 - 如果忽略霍夫曼频率表的开销 - 为每个数据文件选择最佳的前缀码。 没有可以预先生成的单个“霍夫曼”代码而不考虑实际的符号频率。 对于不同的文件,Huffman算法选择的前缀代码通常不同。
当我们确实拥有100,000多个独特元素时,Huffman算法不能很好地压缩 - 霍夫曼频率表的开销变得如此之大,以至于我们经常可以找到一些实际上提供更好的净压缩的其他“次优”前缀代码。 或者也许一些完全不同的data compression algorithm可能在您的应用程序中工作得更好。
“Huffword”实现似乎可以使用大约32,000个左右的独特元素, 但是我见过的绝大多数霍夫曼代码实现都使用了大约257个唯一元素(256个可能的字节值和文本结束指示符)。
您可能会考虑以某种原始的“未压缩”格式将数据存储在磁盘上。 (拥有100,000多个独特元素,您将不可避免地最终以3个或更多字节存储其中的许多元素)。 那些257值的Huffman压缩实现将能够压缩该文件; 他们将该文件的字节重新解释为256个不同的符号。
我的问题是,如果第n个元素的代码长度为n位 当我通过第32届时,它确实更节省空间 只是按原样发送32位数据类型,例如int? 我在方法论中遗漏了什么吗?
前缀码的一个更直观的特征是某些符号(稀有符号)被“压缩”成更长的比特序列。如果您实际上有2 ^ 8个唯一符号(所有可能的8位数字),则强制压缩器使用限制为8位或更少的前缀代码时,无法获得任何压缩。通过允许压缩器扩展稀有值 - 使用超过8位来存储我们知道可以存储在8位中的稀有符号 - 这使得压缩器可以使用少于8位来存储更频繁的符号
相关: Maximum number of different numbers, Huffman Compression