urrower-Wheeler变换
1994年 Michael Burrows 和 David Wheeler在《A Block-sorting Lossless Data Compression Algorithm》一文中共同提出了一种全新的通用数据压缩算法,Burrows-Wheeler Transformation。
burrows和wheeler设计的bwt算法与以往所有通用压缩算法的设计思路都迥然不同。现有比较著名的压缩算法都是处理数据流模型的,一次读取一个或多个字节,BWT使得处理成块的数据成为可能。这种算法的核心思想是对字符串轮转后得到的字符矩阵进行排序和变换。考虑一般的文本应用比如英语文本中the这个字符串经常会被用到,经过BW转换之后,所有的t都被移动到最后并且聚合在一起,这样变换之后的字符串用通用的统计压缩模型(Huffman coding、LZ算法、PPM算法)等进行压缩就能得到更好的压缩比。
编码变换
通过把原始串循环移位,把移位的这些串按照字典序排列。串中的最后一个字符,按顺序输出。同时输出原序列在排序序列中的位置。
以字符串"^BANANA@" 为例。他变换为"BNN^AA@A" 的步骤如下
变换
输入
所有的循环移位
对所有行排序
输出
^BANANA@
^BANANA@
@^BANANA
A@^BANAN
NA@^BANA
ANA@^BAN
NANA@^BA
ANANA@^B
BANANA@^
ANANA@^B
ANA@^BAN
A@^BANAN
BANANA@^
NANA@^BA
NA@^BANA
^BANANA@
@^BANANA
BNN^AA@A
原始串在排序序列中为6(没有特殊说明,都是从0开始计算);
算法描述如下:
function BWT (string s)
create a table, rows are all possible rotations of s
sort rows alphabetically
return (last column of the table)
C语言代码如下
#include
#include
#include
#define BLOCK_SIZE 200000
long length; // 字符串长度
unsigned char buffer[ BLOCK_SIZE ]; // 原始字符串
int indices[ BLOCK_SIZE];
int memcmp_signed = 0;
int _cdecl bounded_cmp( const unsigned int *i1,const unsigned int *i2 )
{
int base = length;
char i = *i1, j = *i2;
while (base --)
{
if (*(buffer+i) == *(buffer+j))
{
i++;
j++;
i%=length;
j%=length;
}
else
{
return *(buffer+i) - *(buffer+j);
}
}
return 0;
}
main( int argc, char *argv[] )
{
int debug = 0;
int i;
for ( ; ; )
{
gets((char*)buffer); // 输入待处理字符串
length = strlen((char*)buffer);
printf("Performing BWT on %ld bytes/n", length );
for ( i = 0 ; i < length ; i++ )
{
indices[ i ] = i; // 第i个循环后的字符串从原始字符串的第i个开始
}
// 对循环移动后的序列排序
qsort( indices,(int)( length ),sizeof( int ),(int (*)(const void *, const void *) ) bounded_cmp );
long last;
for ( i = 0 ; i < length ; i++ )
{
if ( indices[ i ] == 0 )
{
last = i;
putchar( buffer[length - 1]);
}
else
{
putchar( buffer[ indices[ i ] - 1 ]);
}
}
printf( "/nlast = %ld/n", last );
}
return 0;
}
解码过程
待续……