《程序是怎样跑起来的》读书笔记——第六章 亲自尝试压缩数据
- 1 文件以字节为单位保存
- 2 RLE 算法的机制
- 3 RLE 算法的缺点
- 4 通过莫尔斯编码来看哈夫曼算法的基础
- 5 用二叉树实现哈夫曼编码
- 6 哈夫曼算法能够大幅提升压缩比率
- 7 可逆压缩和非可逆压缩
1 文件以字节为单位保存
文件是将数据存储在磁盘等存储媒介中的一种形式。程序文件中存储数据的单位是字节。
文件就是字节数据的集合。用 1 字节(= 8 位)表示的字节数据有 256 种,用二进制数来表示的话,其范围就是 00000000~11111111。如 果文件中存储的数据是文字,那么该文件就是文本文件。如果是图形,那么该文件就是图像文件。在任何情况下,文件中的字节数据都是连 续存储的,大家一定要认识到这一点(图 6-1)。

2 RLE 算法的机制
首先让我们来尝试 一下对存储着 AAAAAABBCDDEEEEEF 这 17 个半角字符的文件(文 本文件)进行压缩。虽然这些文字没有什么实际意义,但是很适合用来 解说 RLE 算法的压缩机制。
思路:“字符 × 重复次数”

像这样,把文件内容用“数据 × 重复次数”的形式来表示的压缩方 法称为 RLE(Run Length Encoding,行程长度编码)算法
。RLE 算法是一种很好的压缩方法,经常被用于压缩传真的图像等 。因为图像文件本质上也是字节数据的集合体,所以可以用 RLE 算法来压缩。
3 RLE 算法的缺点
然而,在实际的文本文件中,同样字符多次重复出现的情况并不 多见。虽然针对相同数据经常连续出现的图像、文件等,RLE 算法可 以发挥不错的效果,但它并不适合文本文件的压缩。

4 通过莫尔斯编码来看哈夫曼算法的基础
为了更好地理解哈夫曼算法
,首先大家要抛弃掉“半角英文数字的 1 个字符是 1 个字节(8 位)的数据”这一概念。文本文件是由不同类 型的字符组合而成的,而且不同的字符出现的次数也是不同的。例 如,在某一个文本文件中,A 出现了 100 次左右,Q 仅用到了 3 次, 类似这样的情况是很常见的。而哈夫曼算法的关键就在于“多次出现 的数据用小于 8 位的字节数来表示,不常用的数据则可以用超过 8 位 的字节数来表示”。A 和 Q 都用 8 位来表示时,原文件的大小就是 100 次 × 8 位 + 3 次 × 8 位 = 824 位,而假设 A 用 2 位、Q 用 10 位来 表示,压缩后的大小就是 100 次 ×2 位+3 次 ×10 位 = 230 位。
🈲️不过有一点需要注意,不管是不满 8 位的数据,还是超过 8 位的 数据,最终都要以 8 位为单位保存到文件中。这是因为磁盘是以字 节(8 位)为单位来保存数据的

“
摩斯密码
莫尔斯编码不是通过语言,而是通过“嗒 嘀 嗒 嘀”这些长点和短点的组合来传递文本信息的。实际上,根据字符种类的不同,莫尔斯电码符号的 长度也是不同的。表 6-2 是莫尔斯编码的示例。大家把 1 看作是短点(嘀),把 11 看作是长点(嗒)即可。

莫尔斯编码把一般文本中出现频率高的字符用短编码来表示。因此,AAAAAABBCDDEEEEEF 这个文本,就变成了 A×6 次 +B×2 次+C×1 次+D×2 次+E×5 次+F×1 次+字符间隔 ×16 = 4 位 ×6 次+8 位 ×2 次+9 位 ×1 次+6 位 ×2 次+1 位 ×5 次+8 位 ×1 次+2 位 ×16 次 = 106 位 ≒ 14 字节。这样文本中列出来的 17 个 字符 = 17 字节,那么摩尔斯电码的压缩比率就是 14÷17 ≒ 82%,并 不太突出。
5 用二叉树实现哈夫曼编码
哈夫曼算法
是指,为各压缩对象 文件分别构造最佳的编码体系,并以该编码体系为基础来进行压缩。 因此,用什么样式的编码(哈夫曼编码)对数据进行分割,就要由各个 文件而定。用哈夫曼算法压缩过的文件中,存储着哈夫曼编码信息和 压缩过的数据。

接下来,我们尝试一下把 AAAAAABBCDDEEEEEF 中的 A~F 这 些字符,按照“出现频率高的字符用尽量少的位数编码来表示”这一原 则进行整理。该表中同时也列出了编码的方案。

不 过,这个编码体系是存在问题的。该问题就是,例如 100 这个 3 位的 编码,它的意思是用 1、0、0 这 3 个编码来表示 E、A、A 呢?还是用 10、0 这两个编码来表示 B 、A 呢?亦或是用 100 来表示 C 呢?这些 都无法进行区分。因此,如果不加入用来区分字符的符号,这个编码(方案)就无法使用。
而在哈夫曼算法中,通过借助 哈夫曼树构造编码体系
,即使在不 使用字符区分符号的情况下,也可以构建能够明确进行区分的编码体 系。

在用枝条连接数据时,我们是从出 现频率较低的数据开始的,这就意味着出现频率越低的数据到达根部 的枝条数就越多。而枝条数越多,编码的位数也就随之增多了。
6 哈夫曼算法能够大幅提升压缩比率
哈夫曼编码表示 AAAAAABBCDDEEEEEF,结果为 00000000000010010 01101011010101010101111,40位= 5字节(这里为不包含哈夫曼编码信 息的情况)。压缩前的数据是 17 字符 = 17 字节,也就是说,我们惊奇 地得到了 5 字节 ÷ 17 字节 ≒ 29% 这样高的压缩率。

7 可逆压缩和非可逆压缩
我们把能还原到压缩前状态的压缩称为 可逆压缩
,无法还原到压 缩前状态的压缩称为 非可逆压缩