原理
数据压缩算法将数据用不同的方式表现出来,目的是减少所需的存储空间ZIP算法是网络通信中广泛使用的数据压缩算法,它是Phil Katz在20世纪80年代中发明的,而ZIP算法的基础是Jacob Ziv和 Abraham Lempel在1977年提出的序列数据压缩通用算法,通常简称为LZ77压缩算法.自1988年发表以来,ZIP算法已在若干数据压缩软件中广泛使用,包括PKZIP、WinZip、WinRAR和gzip ZIP 压缩算法使用两个滑动窗口,将新出现的还没有被压缩的字符串与已经出现过的相同的字符串做匹配,记下此字符串的长度及前后两者的相对位置.如果字符串相对较长,则字符串的长度和相对位置的值就是这个新字符串的一个压缩表示.ZIP算法的这两个滑动窗口分别称为基准窗和前视窗.前视窗位于基准窗之前,两者相邻.当两个窗所包含的字符串被处理后,它们同时向前移动,扫描整个文件,并在移动过程中压缩数据.具体做法如下:令X和Y分别表示当前基准窗和前视窗所覆盖的字符串,令s为Y的最长前缀,而且是X的子序列,则s可由以下两个数值唯一确定:
- 相对距离:基准窗出现的字符串 s 的第一个字符到前视窗出现的字符串 s的距离,以字符为单位.
- 字符长度:字符串s的长度.
如果存储这两个值所用的空间比存储s所用的空间小,在压缩文件中用这两个值取代前视窗中的s就将节省存储空间.注意:原件和压缩文件是两个不同的文件.压缩文件生成后,可删除原件.
为了辨认这两个值,必须对编码进行调整使得这两个值的编码能从文件所用的标准编码区分开来.例如,假如文件所用的编码是8比特ASCII码,则限定字符长度和相对距离这两个值的二进制数的总长度8.在每一个ASCII码前加上一个二进制数字1得9比特加长ASCII码,并在代表这两个数值的二进制数的前面加上一个二进制数字0就能达到这个目的.在两个数值的二进制数的前面加上一个二进制数字0得到的编码称为位置码.具体做法如下:
令
w
1
w_1
w1和
w
2
w_2
w2分别表示基准窗和前视窗可以容纳的字符个数,即基准窗和前视窗的长度分别是
8
w
1
8w_1
8w1和
8
w
2
8w_2
8w2,其中
2
d
−
1
<
w
1
≤
2
d
,
2
l
−
1
<
w
2
≤
2
l
2^{d-1}<w_1≤2^d,2^{l-1}<w_2≤2^l
2d−1<w1≤2d,2l−1<w2≤2l,d和l分别为某正整数,而且
d
+
l
=
8
d+l=8
d+l=8.则在前视窗出现的s将由
(
d
+
l
+
1
)
(d+l+1)
(d+l+1)比特二进制字符串表示,其中第一个二进制字符串为0,用做标识符,紧跟在后面的d比特二进制数表示距离,而最后的l比特二进制数表示长度.这是一个9比特位置码.
9比特位置码很容易从9比特加长ASCII码区别出来.换句话说,对任意用此方法得到的压缩文件,将其还原成原来的ASCII文件是件轻而易举的事.因此,只要
d
+
l
+
1
<
8
∣
s
∣
d+l+1<8|s|
d+l+1<8∣s∣,即在ASCII文件中只要
∣
s
∣
>
1
|s|>1
∣s∣>1,则ZIP算法就能节省存储空间.ZIP算法随后将基准窗和前视窗同时向前移动max{1,|s}个字符,并重复上述步骤,直到前视窗滑出文件之外为止.
案例
下面是用ZIP算法压缩字符串的一个例子.令
w
1
=
18
w_1=18
w1=18及
w
=
7
w_=7
w=7,则
d
=
5
d=5
d=5和
l
=
3
l=3
l=3.考虑如下字符串
" a loop containing a loop is a nested loop"
令
n
b
n_b
nb表示正整数n的二进制表示.对此句子运用ZIP算法(如图5.11所示),得到以下压缩输出:
“a loop containing 017b7bis a nested016b5b”
其中每个字母和空格由9比特加长ASCII码所表示.压缩后的字符串的二进制表示的长度等于
18
×
9
+
9
+
11
×
9
+
9
=
279
18×9+9+11×9+9=279
18×9+9+11×9+9=279比特,
而原句按8比特ASCII编码的长度等于
41
×
8
=
328
41×8=328
41×8=328比特.
因此,ZIP将原句子压缩了将近15%.
如果在股价走势疲软时连内部人士都不去买自己的股票,谁还会去买呢?缺少内部人士的支撑通常会被认为是相当明显的利空信息。