一、课前热身
1. 文件储存的基本单位是什么?
- 答:字节
2. DOC、LZH 和 TXT 这些扩展名中,哪一个是压缩文件的扩展名?
- 答:LZH
3. 文件内容用“数据的值 × 循环次数”来表示的压缩方法是RLE 算法还是哈夫曼算法?
- 答: RLE
4. 在 Windows 计算机经常使用的 SHIFT JIS 字符编码中,1个半角英数是用几个字节的数据来表示的?
- 答:一字节
5. BMP(BITMAP)格式的图像文件,是压缩过的吗?
- 答:没有压缩过
6. 可逆压缩和非可逆压缩的不同点是什么?
- 答:压缩后的数据能复原的是可逆压缩,无法复原的是非可逆压缩,还原会有数据的丢失。
二、 文件以字节为单位保存
- 文件是将数据存储在磁盘等存储媒介中的一种形式。程序文件中存储数据的单位是字节。文件的大小之所以用 ××KB、××MB等来表示,就是因为文件是以字节(B = Byte)为单位来存储的。
- 在任何情况下,文件中的字节数据都是连续存储的。
三、RLE 算法的机制
- 接下来就让我们正式看一下文件的压缩机制。首先让我们来尝试一下对存储着 AAAAAABBCDDEEEEEF 这 17 个半角字符的文件(文本文件)进行压缩。在观察 AAAAAABBCDDEEEEEF 这个数据后,不难看出有不少字符是重复出现的。在字符后面加上重复出现次数,AAAAAABBCDDEEEEEF 就可以用 A6B2C1D2E5F1 来表示。A6B2C1D2E5F1 是 12 个字符也就是 12 字节,因此结果就将原文件压缩了 12 字节 ÷17 字节≒ 70%。
- 像这样,把文件内容用“数据 ×重复次数”的形式来表示的压缩方法称为 RLE(Run Length Encoding,行程长度编码)算法。RLE算法是一种很好的压缩方法,经常被用于压缩传真的图像等 A。因为图像文件本质上也是字节数据的集合体,所以可以用 RLE 算法来压缩。
四、RLE 算法的缺点
- 在实际的文本文件中,同样字符多次重复出现的情况并不多见。虽然针对相同数据经常连续出现的图像、文件等,RLE 算法可以发挥不错的效果,但它并不适合文本文件的压缩。
- 使用 RLE 算法对文本文件进行压缩后,文件却增大了,而且几乎是压缩前的 2 倍。这是因为文本文件中同样字符连续出现的部分并不多。以存储着“This is a pen.”这 14 个字符的文本文件为例,使用 RLE 算法对其进行压缩后,就变成了“T1h1i1s1 1i1s1 1a1 1p1e1n1.1”这样的 28 个字符,是压缩前的 2 倍。由于文章中字符大量连续出现的情况并不多见,因此,使用 RLE 算法后,大部分字符后面都会加上 1,这样一来,压缩后的文件自然变成了之前的 2 倍。
五、用二叉树实现哈夫曼编码
-
哈夫曼算 法 是 哈 夫 曼(D. A. Huffman)于 1952 年提出来的压缩算法。日本人比较常用的压缩软件 LHAA,使用的就是哈夫曼算法。
-
哈夫曼算法是指,为各压缩对象文件分别构造最佳的编码体系,并以该编码体系为基础来进行压缩。因此,用什么样式的编码(哈夫曼编码)对数据进行分割,就要由各个文件而定。用哈夫曼算法压缩过的文件中,存储着哈夫曼编码信息和压缩过的数据。
-
我们尝试一下把 AAAAAABBCDDEEEEEF 中的 A~F 这些字符,按照“出现频率高的字符用尽量少的位数编码来表示”这一原则进行整理。按照出现频率从高到低的顺序整理后,结果就如表 6-3 所示。该表中同时也列出了编码的方案。
-
接下来我们就来看一下如何制作哈夫曼树。自然界的树是从根开始生枝长叶的。而哈夫曼树则是从叶生枝,然后再生根。图 6-5 展示了对 AAAAAABBCDDEEEEEF 进行编码的哈夫曼树的制作过程。大家也尝试绘制一下吧。尝试过 1 次后,应该就能理解哈夫曼树的制作顺序了。
-
接下来,让我们来看一下哈夫曼算法的压缩比率。用图 6-5 得到的哈夫曼编码表示 AAAAAABBCDDEEEEEF,结果为 00000000000010010
01101011010101010101111,40 位 = 5 字节(这里为不包含哈夫曼编码信息的情况)。压缩前的数据是 17 字符 = 17 字节,也就是说,我们惊奇地得到了 5 字节 ÷ 17 字节≒ 29% 这样高的压缩率。表 6-4 是将表 6-1中的文件应用哈夫曼算法的 LHA 进行压缩后的结果,大家可以参考一下。可以看出,不管是哪种类型的文件,都得到了很高的压缩比率。
六、可逆压缩和非可逆压缩
- 我们把能还原到压缩前状态的压缩称为可逆压缩,无法还原到压缩前状态的压缩称为非可逆压缩。