数据压缩——有益无害(2)

那我们怎么才能享受免费午餐呢?你怎么才能在不破坏的情况下,让一块数据或信息比起实际“真实”体积更小,并在之后完美地重构一切东西呢?事实上,人类一直都在这么做,只不过从未想到过罢了。想一下你的每周日程。为简单起见,让我们假设你每天工作8小时,每周工作5天,你用一小时的区间来划分日程。因此,5个工作日的每天都有8个可能的区间,每周一共有40个区间。然后,将你一周的日程传输给其他人,你必须传输40份信息。但如果有人打电话让你安排下周的一个会议,你会通过列出40份分开的信息来描述自己什么时候有空吗?当然不会!最有可能的情况是,你会说些“周一和周二全满,周四和周五下午1点到3点有预约,其余时间有空”之类的话。这就是一个无损数据压缩的例子!和你谈话的人能完全重构出你下周所有40个时段的空闲情况,但你却无须详细列出它们。

你也许会想这种“压缩”是取巧,因为它取决于这一事实:你的日程安排中的绝大多数区块都相同。特别是,周一和周二全天都有预约,因此你能非常快速地描述它们,这周剩下的时间里,除了两个时间段以外都有空,这也很容易描述。这的确是个非常简单的例子。不管怎样,计算机中的数据压缩也是按照这一方法运行的:基本思想是发现数据中彼此相同的部分,并运用某种把戏更高效地描述这些部分。

这在数据包含重复片段时尤其简单。比如,你很有可能想出一个压缩下列数据的好方法:

AAAAAAAAAAAAAAAAAAAAABCBCBCBCBCBCBCBCBCBCAAAAAADEFDEFDEF

如果乍一看还不明显,思考一下你会如何通过电话向某人口述这份数据。和说“A、A、A、A、……、D、E、F”不同的是,我肯定你更有可能会说“21个A,然后是10个BC,接着是6个A,最后是3个DEF”。再比如,要很快地在一张纸上记下这份数据,你可能会写“21A、10BC、6A、3DEF”。在这个例子里,你将这个包含56个字母的原始数据压缩成了只有16个字母的字符串。这不到原体积的三分之一——不错!计算机科学家将这种特别的把戏称为行程长度编码(run–length encoding),因为它将重复的“行程”和行程的“长度”编码在了一起。

不幸的是,行程长度编码只在压缩非常特殊的数据种类上有用。它在实际中也有运用,但大部分时候只和其他压缩算法结合起来使用。比如,传真机就将行程长度编码和另一种被称为霍夫曼编码(Huffman coding)的技术结合起来使用,我们稍后将谈到霍夫曼编码。行程长度编码的主要问题是,数据中的重复片段必须相邻——换句话说,重复部分间不能有其他数据。使用行程长度编码压缩ABABAB很容易(只是3AB),但用相同的把戏压缩ABXABYAB就行不通了。

读书导航