博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BWT(Burrows-Wheeler Transformation)的讲解及java实现
阅读量:4551 次
发布时间:2019-06-08

本文共 3326 字,大约阅读时间需要 11 分钟。

BWT(Burrows-Wheeler Transformation)

1.什么是BWT

   压缩技术主要的工作方式就是找到重复的模式,进行紧密的编码。

BWT(Burrows–Wheeler_transform)将原来的文本转换为一个相似的文本,转换后使得相同的字符位置连续或者相邻,之后可以使用其他技术如: 和  进行文本压缩。

2.BWT原理

2.1 BWT编码

   (1)首先,BWT先对需要转换的文本块,进行循环右移,每次循环一位。可以知道长度为n的文本块,循环n次后重复,这样就得到看n个长度为n的字符串。如下图中的“Rotate Right”列。(其中‘#’作为标识符,不在文本块的字符集中,这样保证n个循环移位后的字符串均布相同。并且定义'#'小于字符集中的任意字符)。

(2)对循环移位后的n个字符串按照字典序排序。如下图中的“Sorted (M)”列。

(3)记录下“Sorted (M)”列中每个字符串的最后一个字符,组成了“L”列。(其中"F"列是“Sorted (M)”列中每个字符串的前缀)

这样,原来的字符串“banana#”就转换为了“annb#aa”。在某些情况下,使用L列进行压缩会有更好的效果。“L”列就是编码的结果。

2.2 BWT解码

因为进行的是循环移位,且是循环左移注意下面的性质:

      1、
L的第一个元素是Text中的最后一个元素
      2、
对于M中的每一行(第一行除外)第一个元素都是最后一个元素的下一个元素。
 也就是说,对于文本块而言,同一行中F是L的下一个元素,L是F的前一个元素。
 
这样,就需要
(1)通过"F"列中的元素,找到他前面的字符,就是对应的同一行“L”列;
(2)通过“L”列中的元素,找到他在“F”列中的对应字符位置。但是“L”中有3个字符a,如何对应F中的3个a呢?因为L是F的前一个元素,多个具有相同前缀的字符串排序,去掉共同前缀后相对次序没有变化。所有遇到多个相同的字符,相对位置不变;
(3)转到(1),直到结束。

      排序后的字符串              BWT变换后的字符串

先在BWT变换后的字符串中找到美元符号"$",和它同一行的字母是B,我们先写下,$B找到B之后我们在右边一栏里找B,与其对应的是A

然后记下$BA,

现在A的在左边是第三次出现的,故在右边一栏里找A,同样是第三次出现的,与之对应的是N,然后记下$BAN,左边的N

是第二次出现的,故在右边一栏里找N同样是第二次出现的,与之对应的是A

然后记下$BANA,现在A的在左边是第二次出现的,故在右边,一栏里找A同样是第二次出现的,与之对应的是N,然后记下$BANAN

左边N的是第一次出现的,故在右边一栏里找N同样是第一次出现的,

与之对应的是A,然后记下$BANANA,现在的A在左边是第一次出现的,故在右边一栏里找A同样是第一次出现的,与之对应的是"$",结束。

package cn.genekang.io.test;import java.util.Arrays;public class BWTtest {    public static void main(String[] args) {        String str = "banana";        System.out.println("输入的字符串是:"+str);        String enCodeStr = enCode(str);        System.out.println("编码后的字符串是:"+enCodeStr);        System.out.println("解码后的字符串是:"+deCode(enCodeStr));    }    // bwt编码    public static String enCode(String line) {        String str = line + "&";        int len = str.length();        // 1.轮转        char[] charArray = str.toCharArray();        char[][] ch = new char[len][len];        for (int i = 0; i < len; i++) {            char[] c_tmp = charArray.clone();            for (int j = 0; j < len; j++) {                ch[i][j] = c_tmp[j];                if (j <= len - 2)                    charArray[j + 1] = c_tmp[j];            }            charArray[0] = c_tmp[len - 1];        }        // 2.排序,按照字典顺序        String[] strings = new String[len];        for (int i = 0; i < len; i++) {            StringBuffer chline = new StringBuffer();            for (char c : ch[i]) {                chline.append(c);            }            strings[i] = chline.toString();        }        Arrays.sort(strings);        // 3.取最后一行        StringBuffer sBuffer = new StringBuffer();        for (String s : strings) {            sBuffer.append(s.substring(len - 1, len));        }        return sBuffer.toString();    }    // bwt解码    public static String deCode(String str) {        int len = str.length();        String[] strArr = new String[len];        for (int i = 0; i < len; i++) {            strArr[i] = str.substring(i, i + 1) + ":" + i;        }        Arrays.sort(strArr);        // for(String string : strArr)        // System.out.println(string);        StringBuffer sb = new StringBuffer();        int num = 0;        int corr = Integer.parseInt(strArr[0].split(":")[1]);        while (num < len-1) {                        sb.append(strArr[corr].split(":")[0]);            corr =Integer.parseInt( strArr[corr].split(":")[1]);            num++;        }        return sb.toString();    }}

 

 

转载于:https://www.cnblogs.com/6tian/p/4076539.html

你可能感兴趣的文章
服务器发送邮件出现Could not connect to SMTP host错误 解决办法
查看>>
sklearn.preprocessing.LabelBinarizer
查看>>
C teaching
查看>>
分隔指定内容,提取章节数
查看>>
this point
查看>>
leetcode 30 Substring with Concatenation of All Words
查看>>
验证登录信息是否合法
查看>>
线程池
查看>>
git版本控制器的基本使用
查看>>
Redis 笔记与总结4 set 和 zset 类型
查看>>
jQuery Ajax 回调函数中调用$(this)的问题 [ 转 ]
查看>>
thymeleaf:字符串拼接+输出单引号
查看>>
springboot:集成fastjson(教训)
查看>>
网络流 Edmons-Karp 算法讲解
查看>>
「NOIP2018模拟9.10」公约数 - 找规律 - gcd
查看>>
使用java理解程序逻辑(15)
查看>>
bzoj 1879 状压dp
查看>>
python 一些特殊用法和坑
查看>>
WIFI密码破解全攻略
查看>>
c++string各种函数
查看>>