最短编辑距离(Edit Distance)【DP】
概念
编辑距离(最短编辑距离,Edit Distance)又称Levenshtein
Distance,“是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。一般来说,编辑距离越小,两个串的相似度越大。”
——引用自百度
分析
- 假设用f[i][j]表示将串a[1…i]转换为串b[1…j]所需的最少操作次数(最短距离)
首先是边界:
①i==0时,即a为空,那么对应的f[0][j]的值就为j:增加j个字符,使a转化为b
②j==0时,即b为空,那么对应的f[i][0]的值就为i:减少i个字符,使a转化为b然后考虑一般情况(这里是DP思想):我们要得到将a[1..i]经过最少次数的操作就转化为b[1..j],那么我们就必须在此之前以最少次数(假设为k次)的操作,使现在的a和b只需再做一次操作或者不做操作就可以使a[1..i]转化到b[1..j]。而“之前”有三种情况:
①将a[1…i]转化为b[1…j-1]
②将a[1..i-1]转化为b[1..j]
③将a[1…i-1]转化为b[1…j-1]第①种情况,只需要在最后将a[j]加上b[1..i]就可以了,总共就需要k+1次操作。
第②种情况,只需要在最后将a[i]删除,总共需要k+1个操作。
第③种情况,只需要在最后将a[i]替换为b[j],总共需要k+1个操作。但如果a[i]刚好等于b[j],就不用再替换了,那就只需要k个操作。- 为了得到最小值,将以上三种情况的最小值作为f[i][j]的值(我前面不是说了f[i][j]表示串a[1…i]转换为串b[1…j]所需的最少操作次数嘛),最后答案在f[n][m]中。
- -
实现(只描述算法部分)
- 初始化。边界情况,用循环嵌套或两个独立的循环都可以做到。
2.循环嵌套遍历f数组,先处理a[i]==b[j]的情况,如不满足,再从三种情况中选择最小的,作为f[i][j]的值。三种情况中,①如果在k个操作里将a[1…i-1]转换为b[1..j],那就可以将a[i]删除,共需k+1个操作,所以是f[i-1][j]+1;②如果在k个操作里将a[1…i]转换为b[1…j-1] ,那就可以加上b[j],共需k+1个操作;③如果我们可以在k个操作里将a[1…i-1]转换为b[1…j-1],那就可以将a[i]转换为b[j],也是共需k+1个操作。(前面已经处理过了a[i]==b[j]的情况)
3.最后的答案是f[][]最后一个元素的值。
图解
我们拿POJ的一个样例来举例。
刚开始是这样的:
现在来填表,填表规则:比较a[i-1]和b[j-1]的值(-1是因为字符数组是从0开始的,而f[][]是从0初始化的,从1开始填,比如说第一个空是f[1][1],却要比较a[0][0]。),如果相等,其值为其上、左上、左三个元素中的最小值;如果不等,则是三个元素中的最小值+1(如果你懂了填表规则,能填了,说明你已经懂了)
过程如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现