你好像明白前缀码的原理了。
许多人(令人困惑)将所有前缀代码称为“霍夫曼代码”。
还有许多其他类型的前缀码——它们将数据压缩成比霍夫曼压缩更少的位数(如果我们忽略传输频率表的开销),但它们中的许多都非常接近(某些类型的数据)并具有其他优势,例如运行速度更快或保证某些最大代码长度(“长度限制前缀代码”)。
如果您有大量唯一符号,则霍夫曼频率表的开销会变得很大——也许其他一些前缀代码可以提供更好的网络压缩。
许多在硬件中进行压缩和解压缩的人对最大码字大小有固定的限制——许多图像和视频压缩算法都指定了“长度受限的霍夫曼码”。
最快的前缀码——universal codes——事实上,包含一系列可以预先生成的位序列,而无需考虑实际符号频率。正如您所提到的,使用这些代码的压缩程序会将最频繁的输入符号与最短的位序列相关联,将次频输入符号与下一个缩短的位序列相关联,依此类推。
例如,一些压缩程序使用Fibonacci codes(一种通用代码),并且总是将最频繁的符号关联到位序列“11”,将次频符号关联到位序列“011” "、"0011" 的旁边、"1011" 的旁边等等。
霍夫曼算法生成的代码在许多方面与通用代码相似——两者都是前缀代码。
但是,正如 Cyan 指出的那样,霍夫曼算法与那些通用代码略有不同。
如果您有 5 个不同的符号,则 Huffman 树将包含 5 个不同的位序列 - 但是,the Huffman algorithm 生成的确切位序列取决于确切的频率。
一个文档的符号计数可能为 { 10, 10, 20, 40, 80 },导致 Huffman 位序列 {0000 0001 001 01 1 }。
另一个文档可能有 {40, 40, 79, 79, 80} 的符号计数,导致霍夫曼比特序列 {000 001 01 10 11}。
尽管这两种情况都恰好有 5 个唯一符号,但在这两个压缩文档中,最常见符号的实际 Huffman 代码非常不同——一个文档中的 Huffman 代码“1”,另一个文档中的 Huffman 代码“11”。
但是,如果您使用 Fibonacci 代码压缩这些文档,则最常见交易品种的 Fibonacci 代码始终相同——每个文档中的“11”。
特别是对于斐波那契,第一个 33 位斐波那契码是“31 个零位,后跟 2 个 1 位”,表示值 F(33) = 3,524,578 。
因此 3,524,577 个唯一符号可以用 32 位或更少的斐波那契码表示。
前缀码的一个更违反直觉的特征是某些符号(稀有符号)被“压缩”成更长的位序列。
如果您实际上有 2^32 个唯一符号(所有可能的 32 位数字),则如果您强制压缩器使用限制为 32 位或更少的前缀代码,则无法获得任何压缩。
如果您实际上有 2^8 个唯一符号(所有可能的 8 位数字),则如果您强制压缩器使用限制为 8 位或更少的前缀代码,则不可能获得任何压缩。
通过允许压缩器扩展稀有值——使用超过 8 位来存储我们知道可以以 8 位存储的稀有符号——或者使用超过 32 位来存储稀有符号我们知道 可以 存储在 32 位中——这让压缩器可以使用少于 8 位——或少于 32 位——来存储更频繁的符号。
特别是,如果我使用斐波那契代码来压缩值表,
其中值包括所有可能的 32 位数字,
必须使用长达 N 位的斐波那契代码,其中 F(N) = 2^32 - 求解 N 我得到
对于最不常用的 32 位符号,N = 47 位。