1 简介
论文题目:A Block-sorting Lossless Data Compression Algorithm
论文来源:Systems Research Center 1994
组织机构:
论文链接:https://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf
代码链接:
1.1 创新
- 提出了一种无损的数据压缩技术(Burrows Wheeler transform),通过对文本块进行可逆变化,使输入中的冗余更容易被简单的编码方案获得。
- 算法是通用的,使用排序根据上下文将字符组合在一起,在文本和非文本数据中均能取得不错的效果。
- 算法的解压速度比压缩速度快。
2 方法
2.1 编码
给定字符串,进行循环移位,得到的字符串根据字典序进行排序,取每个移位字符串的最后一列为L。
例如S=‘abraca’,得到L为caraab,index=1。
代码实现
def rotations(t):
tt = t * 2
return [tt[i:i+len(t)] for i in range(0, len(t))]
def bwm(t):
return sorted(rotations(t))
def bwtViaBwm(t):
return ''.join(map(lambda x: x[-1], bwm(t)))
2.2 解码
编码阶段得到L=caraab,index=1。
- 对L进行字典排序,得到循环列表的第一列F=aaabcr。
- 根据F和L,得到映射T。F[T[j]] = L[j]
- T和index还原原始字符串S。
S = [ N − 1 − i ] = L [ T i [ I ] ] S=[N-1-i]=L[T^i[I]] S=[N−1−i]=L[Ti[I]](其中 T 0 [ x ] = x T^0[x]=x T0[x]=x, T i + 1 [ x ] = T [ T i [ x ] ] T^{i+1}[x]=T[T^i[x]] Ti+1[x]=T[Ti[x]])
代码实现(在输入文本结尾加入$符号表示结尾,因此不需要记录index了):
def rankBwt(bw):
tots = dict()
ranks = []
for c in bw:
if c not in tots:
tots[c] = 0
ranks.append(tots[c])
tots[c] += 1
return ranks, tots
def firstCol(tots):
first = {}
totc = 0
for c, count in sorted(tots.items()):
first[c] = (totc, totc+count)
totc += count
return first
def reverseBwt(bw):
ranks, tots = rankBwt(bw)
first = firstCol(tots)
for c, count in sorted(first.items()):
if c == "$":
rowi = count[0]
t = '$'
while bw[rowi] != '$':
c = bw[rowi]
t = c + t
rowi = first[c][0] + ranks[rowi]
return t
3 实验
实验过程为首先对字符串进行编码,然后move-to-front编码,最后进行哈夫曼编码,
将对循环的排序改为后缀排序。
Q1:对原始字符串扩展k个EOF字符,定义为S’。(K为一个机器字的字符数)
Q2:初始化W[0,…,N-1],W[i]=S’[i,…,i+k-1]
Q3:初始化V=[0,1,…,N-1],算法完成后,V[i]表示第i个字符的字典序。
Q4:以每个后缀的前两个字符为key,对V进行排序。
Q5:对字母表中的字符进行遍历ch,完成Q6、Q7。
Q6:对字母表中的字符进行遍历ch’,对ch ch’开始的后缀进行排序。
Q7:对W的值进行修改,高位为ch(保持不变),低位为i。
实验结果如下图:
输入文本块的长度对实验结果的影响:
对比实验: