BWT(Burrows-Wheeler Transformation)的讲解及java实现

BWT(Burrows-Wheeler Transformation)

1.什么是BWT

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

BWT(Burrows–Wheeler_transform)将原来的文本转换为一个相似的文本,转换后使得相同的字符位置连续或者相邻,之后可以使用其他技术如:Move-to-front 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();

    }

}
时间: 2024-10-31 03:41:39

BWT(Burrows-Wheeler Transformation)的讲解及java实现的相关文章

BWT (Burrows–Wheeler_transform)数据转换算法

转自:http://www.cnblogs.com/xudong-bupt/p/3763814.html 具体分析见:http://blog.csdn.net/windroid/article/details/50570450 1.什么是BWT 压缩技术主要的工作方式就是找到重复的模式,进行紧密的编码. BWT(Burrows–Wheeler_transform)将原来的文本转换为一个相似的文本,转换后使得相同的字符位置连续或者相邻,之后可以使用其他技术如:Move-to-front trans

zookeeper基本讲解(Java版,真心不错)

1. 概述 Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务.名字服务.分布式同步.组服务等. 它有如下的一些特点: 简单 Zookeeper的核心是一个精简的文件系统,它支持一些简单的操作和一些抽象操作,例如,排序和通知. 丰富 Zookeeper的原语操作是很丰富的,可实现一些协调数据结构和协议.例如,分布式队列.分布式锁和一组同级别节点中的“领导者选举”. 高可靠 Zookeeper支持集群模式,可以很容易的解决单点故障问题. 松耦合交

java中Collection框架的讲解

下面要开始java中相关集合框架的学习啦. Are you ready?Let's go~~ 今天要讲解的Java中的Collection框架. 1) 首先查看jdk中Collection类的源码后会发现如下内容: ... * @see AbstractCollection * @since 1.2 */ public interface Collection<E> extends Iterable<E> { // Query Operations 通过查看可以发现Collecti

《深入理解Java集合框架》系列文章

Introduction 关于C++标准模板库(Standard Template Library, STL)的书籍和资料有很多,关于Java集合框架(Java Collections Framework, JCF)的资料却很少,甚至很难找到一本专门介绍它的书籍,这给Java学习者们带来不小的麻烦.我深深的不解其中的原因.虽然JCF设计参考了STL,但其定位不是Java版的STL,而是要实现一个精简紧凑的容器框架,对STL的介绍自然不能替代对JCF的介绍. 本系列文章主要从数据结构和算法层面分析

Java并发(基础知识)—— Java中断机制

上文讲解了Java线程的创建.启动以及停止,在讲到停止线程时说到了Java中断,Java中断是停止线程的一种协作机制,本文打算对Java中断机制进行详细讲解. 在网上搜索Java中断机制,发现两篇好文章,分别如下:Java 理论与实践: 处理 InterruptedException 以及 详细分析Java中断机制,推荐大家仔细阅读. 中断是一种协作机制 必须记住,中断是一种协作机制.当一个线程中断另一个线程时,被中断的线程不一定要立即停止正在做的事情.相反,中断是礼貌地请求另一个线程在它愿意并

Java服务器对外提供接口以及Android端向服务器请求数据

讲解下java服务器是如何对移动终端提供接口的,以什么数据格式提供出去,移动端又是怎么请求服务器,接收以及解析返回数据的. 服务端:还是在原先S2SH框架的项目上(搭建SSH详细步骤及其相关说明),加入Servlet来做对终端提供接口的事情. Android端:用了一个网络访问框架okHttp,向服务器请求数据. 服务端: servlet接收移动端的get.post请求,进行相应逻辑处理后将要返回的数据封装成json格式写出去. 对数据库的操作传统的Servlet是用jdbc,但是操作过于繁琐,

《Java虚拟机精讲》读书笔记-第一章Java体系结构

本章主要讲解了java体系的结构,包括四个方面:java编程语言,字节码,Java API和java虚拟机四部分 并简单介绍了以上四部分,同时对java中的一些新特性进行了介绍,由于我阅读本书的时候java8已经发布,因此其中的一些说是要在后续版本实现的功能已经实现了,如lambda表达式,函数式编程等,最后介绍了OpenJdk的使用和编译 下面对一些看书之前不了解的概念进行学习 lambda表达式 什么是λ表达式 λ表达式本质上是一个匿名方法.让我们来看下面这个例子: public int a

深入理解Java之线程池

原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间. 那么有没有一种办法使得线程可

java的动态代理机制详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于 Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是 java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾. 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Cla