编码 | 解码 | 压缩

> shannon | fano | entropy <

// Shannon-Fano —— 用于数据压缩的自顶向下熵编码

[ENTROPY]

基于熵的编码

使用信息论构造高效的可变长度前缀码。

[TOP-DOWN]

自顶向下算法

递归地按概率将符号划分为两组,接近等概率。

[HISTORIC]

经典历史算法

对现代压缩算法(如 Huffman)有重要启发作用。

>> 技术细节

Shannon-Fano 的工作原理:

Shannon-Fano 编码先根据频率对符号排序,然后将其递归地拆分为两组,使两组的总概率尽量接近。每一次拆分都会在码字后追加一位(左组为 0,右组为 1),最终得到一组前缀无歧义的可变长编码。

编码过程示例:

文本: "AAABBCD" 频率: A:3, B:2, C:1, D:1 拆分: [A] | [B,C,D] 码字: A: 0 B: 10 C: 110 D: 111 编码结果: 0 0 0 10 10 110 111

为什么使用 Shannon-Fano:

  • >实现简单,适合教学与实验
  • >具备不错的压缩率
  • >有重要的历史与理论价值
  • >帮助理解熵编码与前缀码
  • >适合作为 Huffman 之前的过渡概念

>> 常见问题

什么是 Shannon-Fano 编码?

Shannon-Fano 编码是一种基于熵的编码技术,由 Claude Shannon 和 Robert Fano 在 20 世纪 40 年代提出。它是最早使用“按概率分配可变长码字”的算法之一。

Shannon-Fano 和 Huffman 有什么区别?

两者都生成可变长编码,但 Huffman 编码在平均码长上是最优的,而 Shannon-Fano 更简单,结构上接近直观的“按概率二分”。实践中通常采用 Huffman,但学习 Shannon-Fano 有助于理解 Huffman 的设计思想。

符号是如何被拆分的?

首先按频率对符号排序,然后按总概率将它们划分为两组,使两组概率尽量接近。之后对每一组重复该过程,直到每组只剩一个符号为止。

Shannon-Fano 现在还在用吗?

在实际工程中,Shannon-Fano 已几乎完全被 Huffman 编码等更优方法取代。现在它主要作为历史与教学示例,用来解释熵编码、前缀码和数据压缩的核心概念。

// 计算示例

SymbolFreqCodeBits
A15002
B7012
C6102
D61103
E51113

// 代码示例

Frequencies  A=15 B=7 C=6 D=6 E=5      (39 symbols)
1. Sort symbols by frequency (descending).
2. Split the list where the two halves' totals are closest:
   {A,B}=22  |  {C,D,E}=17     -> first bit 0 / 1
3. Recurse on each half until single symbols remain:
   {A}|{B} -> 00, 01      {C}|{D,E} -> 10, 11..   then {D}|{E} -> 110, 111
Total   15*2 + 7*2 + 6*2 + 6*3 + 5*3 = 89 bits
Huffman on the same data: A=1 bit, others 3 bits -> 87 bits

>> 更多问题

问:Shannon-Fano 与哈夫曼编码有何不同?

答:Shannon-Fano 自上而下,把排序后的符号表分成频率总和尽量接近的两半;哈夫曼则自下而上,不断合并最稀有的符号。哈夫曼被证明是最优的,Shannon-Fano 则不一定。

问:Shannon-Fano 总是最优吗?

答:不是。示例中它需要 89 位,而哈夫曼只需 87 位。两者都产生前缀码,但 Shannon-Fano 的划分规则可能选出不利的切分。

问:Shannon-Fano 用在哪里?

答:主要作为历史与教学方法(Claude Shannon 与 Robert Fano,1948/49 年)。ZIP 的 IMPLODE 算法中有其变体;现代压缩器多用哈夫曼或算术编码。

其他语言