图解BWT(Burrows-Wheeler Transform) 算法

news/2025/2/10 9:25:09/

Burrows-Wheeler Transform (BWT) 是一种数据转换算法, 主要用于数据压缩领域. 它由 Michael Burrows 和 David Wheeler 在 1994 年提出, 广泛应用于无损数据压缩算法(如 bzip2)中. BWT 的核心思想是通过重新排列输入数据, 使得相同的字符更容易聚集在一起, 从而提高后续压缩算法的效率.


BWT__4">1. BWT 的基本概念

BWT 是一种可逆的变换, 它不会改变数据的内容, 而是通过重新排列数据的顺序, 使得数据更容易被压缩. BWT 的主要特点是:

  • 局部相似性增强: 将输入字符串中的相似字符聚集在一起.
  • 可逆性: 变换后的数据可以通过逆变换恢复为原始数据.

BWT__13">2. BWT算法步骤

2.1 Naive 方法

BWT算法步骤如下:

步骤 1: 生成所有循环移位

假设输入字符串为 S, 长度为 n. 首先, 生成 S 的所有循环移位(cyclic rotations).

例如, 对于字符串 "banana$"($符号是结束符, 不存在于输入串中), 其循环移位包括:

banana$
anana$b
nana$ba
ana$ban
na$bana
a$banan
$banana

这里请读者思考一个问题: 如果没有结束符$, 那么是否能够恢复原始字符串?

步骤 2: 按字典序排序

将所有循环移位按字典序排序. 排序后得到的结果被称为BW矩阵. 对于 "banana$", 排序后的结果为:

$banana
a$banan
ana$ban
anana$b
banana$
na$bana
nana$ba
步骤 3: 提取最后一列

从排序后的循环移位中提取最后一列字符, 形成 BWT 变换后的字符串. 对于 "banana$", 最后一列是:

$banan[a]
a$bana[n]
ana$ba[n]
anana$[b]
banana[$]
na$ban[a]
nana$b[a]

因此, BWT 变换后的结果为 "annb$aa".

再举一些例子:

字符串BWT
"mississippi$""ipssm$pissii"
a_friend_in_need_is_a_friend_indeed$""dsaadddn$_enneneednii__rr___ieei_ffi"
"It_was_the_best_of_times,_it_was_the_worst_of_times$""ss$e,ttssfftteww_hhmmbootttt_ii__woeeaaressIi_______"

从这些例子可以看出, 相同的字母容易成块出现.

代码实现
python">def bwt_transform(s):"""对字符串 s 进行 BWT 变换"""s = s + '$'n = len(s)# 生成所有循环移位rotations = [s[i:] + s[:i] for i in range(n)]# 按字典序排序rotations_sorted = sorted(rotations)# 提取最后一列last_column = ''.join([row[-1] for row in rotations_sorted])return last_column

BWT_93">2.2 使用 SA 数组高效计算 BWT

观察上面的例子, 可以发现: 由于'$'符号的 ASCII 小于任何一个字母(a-z,包含大小写), 这意味着比较时不会用到$符号之后的字符串, 可以删去他们. 排序结果等价于后缀数组.

Bwt vs SA

解决了排序问题之后接着需要关注第二个问题, 即最后的字母的确定. 这个问题比较简单, 因为所有的序列都是循环产生的, 所以序列的最后一位字母其实就是首字母的左侧字母. 用公式表示就是:

B W T [ i ] = { S [ S A [ i ] − 1 ] if  S A [ i ] > 0 $ if  S A [ i ] = 0 BWT[i] = \begin{cases} S[SA[i] - 1] & \text{if } SA[i] > 0 \\ \$ & \text{if } SA[i] = 0 \end{cases}


http://www.ppmy.cn/news/1570823.html

相关文章

浏览器原理:渲染流程、重绘与回流,以及跨域解决方案

三个前端面试问题:渲染流程、重绘与回流,以及跨域解决方案。让我一个一个来思考如何组织这些内容。 首先是渲染流程,从输入URL到页面渲染的过程。我记得这个过程大致包括DNS解析、TCP连接、HTTP请求、服务器响应、浏览器解析和渲染等步骤。但…

网络安全 纵向是什么意思 网络安全维度

信息安全工程师-网络信息安全概述 网络信息安全相关概念 网络信息安全的发展历经了通信保密、计算机安全、信息保障、可信计算等阶段。狭义上的网络信息安全特指网络信息系统的各组成要素符合安全属性的要求,即机密性、完整性、可用性、抗抵赖性、可控性。广义上的…

vue3中使用print-js组件实现打印操作

第一步&#xff1a;安装依赖 yarn add print-js 第二步&#xff1a;创建打印组件&#xff1a;PrintHtmlComp.vue <template><div id"printArea_123456789"><!-- 默认插槽&#xff0c;传入打印内容 --><slot></slot></div>…

Android studio 编译速度增加

在gradle.properties增加如下代码&#xff0c;作用看注释 # Gradle 和 Kotlin 支持增量编译&#xff0c;只编译有改动的部分 kotlin.incrementaltrue # Gradle 支持并行构建&#xff0c;充分利用多核 CPU org.gradle.paralleltrue # Gradle 构建缓存可以缓存任务输出&#xff…

深度学习的图像生成

以下将分别使用 PyTorch 和 TensorFlow 实现基于深度学习的图像生成&#xff0c;这里主要介绍生成对抗网络&#xff08;GAN&#xff09;和变分自编码器&#xff08;VAE&#xff09;两种经典模型。 使用 PyTorch 实现简单的 GAN 进行图像生成 1. 安装必要的库 pip install to…

51单片机之使用Keil uVision5创建工程以及使用stc-isp进行程序烧录步骤

一、Keil uVision5创建工程步骤 1.点击项目&#xff0c;新建 2.新建目录 3.选择目标机器&#xff0c;直接搜索at89c52选择&#xff0c;然后点击OK 4.是否添加起吊文件&#xff0c;一般选择否 5.再新建的项目工程中添加文件 6.选择C文件 7.在C文件中右键&#xff0c;添加…

【数据结构】(7) 栈和队列

一、栈 Stack 1、什么是栈 栈是一种特殊的线性表&#xff0c;它只能在固定的一端&#xff08;栈顶&#xff09;进行出栈、压栈操作&#xff0c;具有后进先出的特点。 2、栈概念的例题 答案为 C&#xff0c;以C为例进行讲解&#xff1a; 第一个出栈的是3&#xff0c;那么 1、…

Linux 创建进程 fork()、vfork() 与进程管理

Linux 创建进程 fork、vfork、进程管理 一、Linux的0号、1号、2号进程二、Linux的进程标识三、fork() 函数1、基本概念2、函数特点3、用法以及应用场景&#xff08;1&#xff09;父子进程执行不同的代码&#xff08;2&#xff09;进程执行另一个程序 4、工作原理 四、vfork() 函…