最近看了名为一部《硅谷》的美剧,讲述了硅谷的一个创业故事。它们公司的一个创新点就是数据压缩。在当前大数据的背景下,数据压缩一方面有利于数据的存储、另一方面有利于数据的传播。无损压缩是要的保证信息不丢失的前提下尽可能的将数据变得更小,因为信息不丢失,所以能够完整的恢复回压缩之前状态。
数据压缩算法的一个特点就是要去寻找原始数据中的规律,从而设计最优化的编码。对于不同类型的文件,比如音频、视频、图片文件,各自有着自己的数据特点,因此能够为之设计出不同的适合各自的压缩算法。本文要讲的是通用的三种的经典无损压缩算法,分别是Shannon-Fano 编码,Huffman 编码,LZW(Lempel-Ziv-Welch) 编码。
Shannon-Fano算法 香农-范诺算法的核心是分治后编码。每次进行二分然后编码,这使得编码能够保证互不为前缀,且频度高的编码尽量短。 Shannon-Fano算法的主要步骤: 1. 统计每种字符(1个字节)的频度,对其从大到小排序,构成一个降序数组。 2. 二分划分,使得左右两侧的频度和尽可能接近。然后分配一个编码位,左边分配0、右边分配1,然后递归继续划分。 3. 直到划分到只有1个字符为止。 压缩成的文件: 压缩文件要写入每个编码对应的原字符,这样才能够完成解压缩。
Huffman 压缩算法
霍夫曼算法的核心是根据每种字符(1个字节)在文件中的出现频率来设计一套互相不为前缀的霍夫曼编码。出现频率越高的字符,其编码会越短,从而到达压缩的目的。
Huffman算法的主要步骤:
1. 统计每个字符的出现频度。
2. 按频度合并构造出霍夫曼二叉树。
3. 由二叉树生成每个字符对应的非前缀二进制编码。
压缩成的文件:
压缩文件中要写入每个编码对应的原字符,这样才能够完成解压缩。
LZW 压缩算法 LZW的全称是Lempel-Ziv-Welch,它是在扫描动态过程动态生成字符串(字节长度不限)的编码,并在之后的扫描中使用编码。 LZW算法的主要步骤: 1. 建立一个压缩字典,开始对文件顺序扫描。 2. 遇到第一次出现的字符串时,把它放入压缩字典中,并用一个编码来表示,这个编码与此字符串在串表中的位置有关,并将这个编码存入压缩文件中。 3. 遇到不是第一次出现的字符串时,即可用压缩字典中的对应编码来代替,并将这个编码存入文件中。 压缩成的文件: 压缩完成后可将压缩字典丢弃,不需要存入压缩文件,因为解压过程会重新扫描并生成和压缩过程时一样的压缩字典。
稍后会在Github上贴出了三种压缩算法的实现,点这里。