一、RLE算法机制
对 AAAAAABBCDDEEEEEF 这17个半角字符的文件(文本文件)进行压缩。虽然这些文字没有什么实际意义,但是很适合用来描述RLE的压缩机制
由于半角字符(其实就是英文字符)是作为1个字节保存在文件中的,所以上述的文件大小就是17字节。如下图:
17个英文字符占用空间:
如何才能压缩该文件呢?只要能够使文件小于17字节,我们可以使用任何压缩算法
最显而易见的一种压缩方式就是把相同的字符 去重化,也就是 字符 * 重复次数 的方式进行压缩,所以上面文件压缩后就会变成下面这样:
文件压缩后的文件大小:
从图中可以看出,AAAAAABBCDDEEEEEF的17个字符成功被压缩成了 A6B2C1D2E5F1 的12个字符,也就是 12/17 = 70% ,压缩成功了
像这样,把文件容易用 数据* 重复次数 的形式来表示压缩方法称为 RLE(Run Length Encoding,行程长度编码)算法。RLE算法是一种很好的压缩方法,经常用于压缩传真的图像等。因为图像文件的本质也是字节数据的集合体,所以可以用RLE算法进行压缩
二、RLE算法的缺点
RLE的压缩机制比较简单,所以RLE算法的程序也比较容易编写,所以使用RLE的这种方式更能让你体会到压缩思想,但是RLE只针对特定序列的数据压缩,下面式RLE算法压缩汇总:
文件类型 | 压缩前文件大小 | 压缩后文件大小 | 压缩比率 |
文本文件 | 14862字节 | 29065字节 | 199% |
图像文件 | 96062字节 | 38328字节 | 40% |
EXE文件 | 24576字节 | 15198字节 | 62% |
通过上表可以看出,使用RLE对文本文件进行压缩后的数据不但没有减小,反而增大了!几乎是压缩前的两倍!因为文本字符中连续的字符并不多见。
就像上面的示例一样,RLE算法只针对 连续 的字节序列压缩效果比较好,假如有一连串不相同的字符该怎么压缩呢? 比如说 ABCDEFGHIJKLMNOPQRSTUVWXYZ ,26个英文字母所占空间应该是26个字节,我们用RLE压缩算法压缩后的结果为:
A1B1C1D1E1F1G1H1I1J1K1L1M1N1O1P1Q1R1S1T1U1V1W1X1Y1Z1,所占用52个字节,压缩完成后的容量没有减少,反而增大了,这显然不是我们想要的结果,所有这种情况下下就不能再使用RLE进行压缩
三、哈夫曼算法和莫尔斯编码
下面是另一个压缩算法,即哈夫曼算法。在了解哈夫曼算法之前,必须舍弃 半角英文数组的1个字符是1个字节(8位)的数据。下面式哈夫曼算法的基本思想
文本文件是由不同类型的字符组合而成的,而且不同字符出现的次数也是不一样的。例如,在某个文本文件中,A出现了100次左右,Q仅仅用到了3次,类似这样的情况很常见。哈夫曼算法的关键就在于多次出现的数据用小于8位的字节数表示,不常用的数据则可以使用超过8位的字节数表示。A和Q都用8位表示时,原文件的大小就是100次 * 8位 + 3位 * 8位 = 842位,假设A用2位,Q用10位来表示就是2 * 100 + 3 * 10 = 230位
不过需要注意的是,最终磁盘的存储都是以8位为一个字节来保存文件的
莫尔斯编码在以前的美剧和战争片的电影,在通信的时候经常采用摩尔斯编码来传递信息
下面式莫尔斯编码的示例,可把1看作短点(嘀),把11看作是长点(嗒即可)
莫尔斯编码一般把文本中出现最高频率的字符用 短编码 来表示。如表所示,假如表示短点的为是1,表示长点的位是11的话,那么E(嘀)这个数据的字符就可以用1来表示,C(滴答滴答)就可以用9位的 110101101 来表示。在实际的莫尔斯编码中,如果短点的长度是1,长点的长度就是3 ,短点和长点的间隔就是1。这里的长度指的就是声音的长度。比如我们想用上面的AAAAAABBCDDEEEEEF 的例子来用莫尔斯编码重写,在莫尔斯编码中,各个字符之间需要加入表示时间间隔的符号。这里我们用 00 加以区分
所有,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字节
所以使用莫尔斯电码的压缩比为 14 / 17 = 82% ,效率并不太突出