【动态规划】求解编辑距离问题

目录

  • 问题描述
  • 递推关系
  • 运行实例
  • 时空复杂度优化
  • Hirschberg 算法

问题描述

编辑距离问题是求解将⼀个字符串转换为另⼀个字符串所需的插⼊、删除、替换的最小次数。 C O M M O M → s u b C O M M U M → s u b C O M M U N → i n s C O M M U N E \mathbb{COMMOM} \overset{sub}{\rightarrow} \mathbb{COMMUM} \overset{sub}{\rightarrow}\mathbb{COMMUN} \overset{ins}{\rightarrow} \mathbb{COMMUNE} COMMOMsubCOMMUMsubCOMMUNinsCOMMUNE上述将单词 COMMOM 变为 COMMUNE 共需要经过至少3次操作。

对编辑距离进行可视化,可以得到序列比对

COMMOM-
COMMUNE
  • 第一行的空格表示插入
  • 第二行的空格表示删除
  • 具有不同字符的列表示替换

编辑距离 = 序列比对中具有不同字符的列数

最小编辑距离 = 最优序列比对中具有不同字符的列数

编辑距离问题也可以这么表述:
对于给定字符串 A [ 1... m ] A[1...m] A[1...m] B [ 1... n ] B[1...n] B[1...n] 求解他们的最小编辑距离 D ( m , n ) D(m,n) D(m,n)


递推关系

假设对 ∀ i < m , ∀ j < n \forall i<m,\forall j<n i<m,j<n,可以计算 A [ 1... i ] A[1...i] A[1...i] B [ 1... j ] B[1...j] B[1...j]的最小编辑距离 D ( i , j ) D(i,j) D(i,j)

COMMOM-
COMMUNE

考虑 A [ 1... m ] A[1...m] A[1...m] B [ 1... n ] B[1...n] B[1...n] 的最优比对,可以发现如下规律:

  1. 最后⼀列不可能是两个空格
  2. 某个串为空串时,最小编辑距离是另⼀个串的长度
  3. A [ m ] A[m] A[m] B [ n ] B[n] B[n] 都存在: D ( m , n ) = D ( m − 1 , n − 1 ) + ( A [ m ] = B [ n ] ? 0 : 1 ) D(m,n) =D(m − 1,n − 1) + (A[m] = B[n]?0 : 1) D(m,n)=D(m1,n1)+(A[m]=B[n]?0:1)
  4. A [ m ] A[m] A[m] B [ n ] B[n] B[n] 有一方为空,删除不为空的那一个: D ( m , n ) = { D ( m − 1 , n ) + 1 A [ m ] a n d − D ( m , n − 1 ) + 1 B [ n ] a n d − D(m,n) = \begin{cases} D(m − 1,n) + 1 & A[m]\quad and \quad- \\ D(m, n − 1) + 1 & B[n]\quad and \quad- \\ \end{cases} D(m,n)={D(m1,n)+1D(m,n1)+1A[m]andB[n]and
  5. 综上,只需要沿着三条路径递归得到最小的那条 D ( m , n ) = { i i f j = 0 j i f i = 0 min ⁡ { D ( m − 1 , n ) + 1 D ( m , n − 1 ) + 1 D ( m − 1 , n − 1 ) + ( A [ m ] = B [ n ] ? 0 : 1 ) o t h e r w i s e D(m,n) = \begin{cases} i &if\quad j=0\\ j &if\quad i=0 \\ \min \begin{cases} D(m − 1,n) + 1 \\ D(m, n − 1) + 1 \\ D(m − 1,n − 1) + (A[m] = B[n]?0 : 1) \end{cases} &otherwise \end{cases} D(m,n)= ijmin D(m1,n)+1D(m,n1)+1D(m1,n1)+(A[m]=B[n]?0:1)ifj=0ifi=0otherwise
  6. 时间复杂度: O ( m n ) O(mn) O(mn) ; 空间复杂度: O ( m n ) O(mn) O(mn)

运行实例

在这里插入图片描述
对于每个 D [ i , j ] D[i,j] D[i,j], 都可以通过 D [ i − 1 , j − 1 ] D[i-1,j-1] D[i1,j1]; D [ i − 1 , j ] D[i-1,j] D[i1,j]; D [ i , j − 1 ] D[i,j-1] D[i,j1]这三个点得到而这三个点又分别对应 替换;删除;插入三种操作。

通过上述递推关系,我们可以自上而下,自左向右构造记录表。在填完记录表后右下角的那个值即为最小编辑距离。接着就是使用回溯的方式,构造满足最小编辑距离的最优比对(如下图右侧所示)
在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>using namespace std;// 计算最小编辑距离,并返回最小编辑距离的值,计算编辑距离表dp
int minEditDistance(const string& word1, const string& word2, vector<vector<int>>& dp) {int m = word1.length();int n = word2.length();for (int i = 0; i <= m; ++i) {for (int j = 0; j <= n; ++j) {if (i == 0) {dp[i][j] = j;}else if (j == 0) {dp[i][j] = i;}else if (word1[i - 1] == word2[j - 1]) {dp[i][j] = dp[i - 1][j - 1];}else {dp[i][j] = 1 + min({ dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] });}}}return dp[m][n];
}// 通过回溯法找到所有满足最小编辑距离的操作序列。
void findAllSequences(const string& word1, const string& word2, int i, int j, const string& sequence, vector<string>& sequences, vector<vector<int>>& dp) {if (i == 0 && j == 0) {sequences.push_back(sequence);return;}if (i > 0 && j > 0 && word1[i - 1] == word2[j - 1]) {findAllSequences(word1, word2, i - 1, j - 1, "No operation: " + string(1, word1[i - 1]) + " -> " + string(1, word2[j - 1]) + "\n" + sequence, sequences, dp);}if (i > 0 && j > 0 && dp[i][j] == dp[i - 1][j - 1] + 1) {findAllSequences(word1, word2, i - 1, j - 1, "Replace: " + string(1, word1[i - 1]) + " -> " + string(1, word2[j - 1]) + "\n" + sequence, sequences, dp);}if (i > 0 && dp[i][j] == dp[i - 1][j] + 1) {findAllSequences(word1, word2, i - 1, j, "Delete: " + string(1, word1[i - 1]) + " \n" + sequence, sequences, dp);}if (j > 0 && dp[i][j] == dp[i][j - 1] + 1) {findAllSequences(word1, word2, i, j - 1, "Insert: " + string(1, word2[j - 1]) + " \n" + sequence, sequences, dp);}
}int main() {string word1 = "ALTRUISTIC";string word2 = "ALGORITHM";vector<vector<int>> dp(word1.length() + 1, vector<int>(word2.length() + 1, 0));int minDistance = minEditDistance(word1, word2, dp);cout << "Minimum Edit Distance between " << word1 << " and " << word2 << " is: " << minDistance << endl;vector<string> sequences;findAllSequences(word1, word2, word1.length(), word2.length(), "", sequences, dp);cout << "Operations to convert " << word1 << " to " << word2 << " are: " << endl;for (const string& seq : sequences) {cout << seq << "----------"<< endl;}return 0;
}

运行结果:

在这里插入图片描述


时空复杂度优化

现在我们已经可以计算最小编辑距离,同时构造出最优比对。他们的时空复杂度总结如下:

计算最小编辑距离构造最优比对
时间 O ( m n ) O(mn) O(mn) O ( m + n ) O(m+n) O(m+n)
空间 O ( m n ) O(mn) O(mn) O ( m n ) O(mn) O(mn)

从实际情况来看, O ( m n ) O(mn) O(mn) 的空间比 O ( m n ) O(mn) O(mn) 的时间更难满足,比如当 m = n = 1 0 5 m = n = 10^5 m=n=105

  • 时间上:执行 1 0 10 10^{10} 1010次指令大约需要10秒(假设CPU每秒执行 1 0 9 10^9 109条指令)
  • 空间上:需要 1 0 10 10^{10} 1010bits,大约 40 GB

那么能否使用 O ( m + n ) O(m+n) O(m+n) 的空间来构造最优比对呢?

答:可以使用 Hirschberg 算法。


Hirschberg 算法

Hirschberg 算法是一种高效的线性空间动态规划算法。它通过使用分治策略来降低空间复杂度,从而在线性空间内计算最优比对。

该算法的思想基于以下洞察力:

  • 在动态规划算法中,通常使用二维矩阵来存储中间状态,这导致了 O ( m n ) O(mn) O(mn) 的空间复杂度。
  • 但实际上,可以通过观察计算过程中的对称性,将动态规划的空间复杂度降低到 O ( m + n ) O(m+n) O(m+n)

在这里插入图片描述
在计算动态规划的过程中,我们观察到 D ( i , j ) D(i,j) D(i,j) 的计算仅依赖于 D ( i − 1 , j ) D(i-1,j) D(i1,j) D ( i , j − 1 ) D(i,j-1) D(i,j1) D ( i − 1 , j − 1 ) D(i-1,j-1) D(i1,j1)。基于此,我们可以利用两个长度为 n 的一维数组来存储中间状态,每次只需要保留上一行和当前行的信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/147181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

八个开源免费单点登录(SSO)系统

使用SSO服务可以提高多系统使用的用户体验和安全性&#xff0c;用户不必记忆多个密码、不必多次登录浪费时间。下面推荐一些市场上最好的开源SSO系统&#xff0c;可作为商业SSO替代。 单点登录&#xff08;SSO&#xff09;是一个登录服务层&#xff0c;通过一次登录访问多个应…

TensorRt推理加速框架Python API服务器部署教程以及运行Helloworld程序

一、确认cuda工具包和n卡相关驱动是否安装 在终端中输入以下命令&#xff1a; nvcc -V如果出现以下提示&#xff0c;则已经成功安装 在终端中输入以下命令&#xff1a; nvidia-smi如果出现即为成功&#xff0c;我在这里就不去介绍怎么下载cuda和驱动怎么下载了&#xff0c;…

探索NLP中的核心架构:编码器与解码器的区别

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测

分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测 目录 分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测分类效果基本描述程序设计参考资料 分类效果…

使用Spring Boot实现大文件断点续传及文件校验

一、简介 随着互联网的快速发展&#xff0c;大文件的传输成为了互联网应用的重要组成部分。然而&#xff0c;由于网络不稳定等因素的影响&#xff0c;大文件的传输经常会出现中断的情况&#xff0c;这时需要重新传输&#xff0c;导致传输效率低下。 为了解决这个问题&#xff…

十三、Docker的安装

0.安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版&#xff08;免费&#xff0c;支持周期 7 个月&#xff09;&#xff0c;EE 即企业版&#xff0c;强调安全&#xff0c;付费使用&#xff0c;支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道…

联想笔记本电脑触摸板失灵了怎么办

这里写自定义目录标题 thinkbook笔记本电脑触摸板失灵 thinkbook笔记本电脑触摸板失灵 由于重装系统&#xff0c;导致笔记本的触控板失灵&#xff0c; 网上说的办法有 1、按键盘上的ctrlf6键&#xff0c;打开触控板功能&#xff1a;无效 2、设置——>设备——>触控板&am…

【powershell】入门和示例

▒ 目录 ▒ &#x1f6eb; 导读开发环境 1️⃣ 简介用途IDE解决此系统上禁止运行脚本 2️⃣ 语法3️⃣ 实战数据库备份执行循环拷贝文件夹 &#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x1f6eb; 导读 开发环境 版本号描述文章日期2023-11-17操作系统Win10 - 22H21904…

23111709[含文档+PPT+源码等]计算机毕业设计基于Spring Boot智能无人仓库管理-进销存储

文章目录 **软件开发环境及开发工具&#xff1a;****功能介绍&#xff1a;****论文截图&#xff1a;****数据库&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 软件开发环境及…

SQL server从安装到入门(一)

文章目录 彻底安装怎么安装&#xff1f;Polybase要求安装orcale jre 7更新 51或更高版本&#xff1f;安装完怎么配置&#xff1f;没有SSMS&#xff1f; 熟悉一下SMSS&#xff01; 根据本人实际安装和初步使用SQL server的过程中&#xff0c;经历的一些关键性的步骤和精品文章。…

问卷工具价格一览:合理定价,满足您的预算需求

在市场调研、市场营销和客户反馈收集等方面&#xff0c;问卷调查是一项重要而有效的工具。而在众多的问卷工具中&#xff0c;Zoho Survey以其丰富的功能和灵活的定价模式而备受关注。Zoho Survey的定价如何&#xff1f;今天我们来聊一聊。 Zoho Survey提供了多种定价方案&…

ROS 学习应用篇(九)ROS中launch文件的实现

launch文件就好比一个封装好的命令库&#xff0c;我们按照在终端中输入的代码指令&#xff0c;全部按照launch语言格式封装在一个launch文件中&#xff0c;这样以后执行的时候&#xff0c;就可以不用开很多终端&#xff0c;一条一条输入代码指令。 lauch文件的语言风格很想我之…

用Postman发送xml数据

启动Postman&#xff1a; 点击左上角的“New”&#xff0c;在弹出窗中选择HTTP&#xff1a; 选择POST方法&#xff1a; 点击Body&#xff1a; 选择raw&#xff1a; 在右侧的下拉列表中选择XML&#xff1a; 在下面的输入框中输入或者从其它地方拷贝XML文本&#xff1a;…

websocket学习

写在前面 新公司用到了websocket技术&#xff0c;所以这里学习下。 1&#xff1a;Java原生 1.1&#xff1a;maven <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.5.3</ver…

【高并发内存池】第一篇 项目简介及定长内存池

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

Android 实现三维空间坐标系(WebView与JS交互,支持多条曲线,可设置坐标轴翻转等)

全部代码已经上传&#xff0c;点击上方进行下载 支持多条曲线的绘制&#xff0c;可旋转拖动放大缩小 1.布局文件&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/…

plantuml最原始的主题如何设置

在startuml下一行添加 skin rose startuml skin rose:Hello world; :This is defined on several **lines**;enduml 效果如下&#xff1a; plantuml官网地址如下&#xff1a; ​​​​​​使用简单的文字描述画UML图的开源工具。轻松从简单的文字说明创建UML图。也有许多种可…

一键云端,AList 整合多网盘,轻松管理文件多元共享!

hello&#xff0c;我是小索奇&#xff0c;本篇教大家如何使用AList实现网盘挂载 可能还是有小伙伴不懂&#xff0c;所以简单介绍一下哈 AList 是一款强大的文件管理工具&#xff0c;为用户提供了将多种云存储服务和文件共享协议集成在一个平台上的便利性。它的独特之处在于&am…

Unity中Shader矩阵的转置矩阵

文章目录 前言一、转置的表示二、转置矩阵三、转置矩阵的总结1、(A^T^)^T^ A2、(A B)^T^ A^T^ B^T^3、(kA)^T^ kA^T^ (k为实数)4、(AB)^T^ B^T^A^T^5、如果 A A^T^ 则称A为对称矩阵6、如果 AA^T^ I(单位矩阵)&#xff0c;则称 A 为正交矩阵&#xff0c;同时 A^T^ A^-1…

复杂数据统计与R语言程序设计实验二

1、创建一个对象&#xff0c;并进行数据类型的转换、判别等操作&#xff0c;步骤如下。 ①使用命令清空工作空间&#xff0c;创建一个对象x&#xff0c;内含元素为序列&#xff1a;1&#xff0c;3&#xff0c;5&#xff0c;6&#xff0c;8。 ②判断对象x是否为数值型数据。 ③…