【动态规划】最小编辑距离(字符串A到字符串B变化最少要多少步)

2 篇文章 0 订阅
2 篇文章 0 订阅

最小编辑距离是一道非常经典的动态规划问题。

设A 和B 是2 个字符串。要用最少的字符操作将字符串A 转换为字符串B。 
这里所说的字符操作包括 
(1)删除一个字符; 
(2)插入一个字符; 
(3)将一个字符改为另一个字符。 
将字符串A变换为字符串B 所用的最少字符操作次数也称为字符串A到B 的编辑距离,记为 d(A,B)。 
试设计一个有效算法,对任给的2 个字符串A和B,计算出它们的编辑距离d(A,B)。 

为什么要把这个问题又搬出来呢?因为我发现,网络上有好多错误代码,错误思路,这种错误代码,流传甚广,被多个博客学习又再次推广发表。我觉得应该纠正一下了。

先说一下错误的版本。以下位置坐标皆从0开始计数。

凡是用到这张图的,全是错误的!

为什么这么说呢?我讲下每一个单元格的数字代表的意义。如上图所示,比如(0,6)位置的数字6 代表字符串“abcdrfg”变为字符串“a”需要的最少步数为6,再比如(1,1,)位置处的数字1代表字符串“ab”变为字符串“aa”需要的最少步数为1。

乍一看,这张图也没问题啊,然而这种写法是错误的,这张图成立只基于两个字符串的首字母相同的情况。配有这张图的大部分博客中的代码都是错误的。比如“a”和“b”,也会检测为需要0步。

真正的图为:

该图中示例为字符串“daaqerdwq”转化为字符串“aswdreqew”。

此时我们可以看到位于(2,2)位置的数字1,对应的是字符串“d”转化为字符串“a”互相转化需要的最少步数。最右下角的褐色区域的数字8,代表字符串“daaqerdwq”转化为字符串“aswdreqew”需要的最小步数。

这个思路是怎么来的呢?首先假设两个字符串都为空,则需要0步就可转化。所以表格最左上角要写0,然后字符串A加入一个字符‘d’,此时需要1步才能做到转化,同理,若是B为空字符串,A字符串有几个字符,就要做几步删除操作。

若是字符串B中有一个字符,如上图中的“a”,重复A字符串从“ ”到“daaqerdwq”不断加入字符的过程,即可得出如下规律

 D[i][j]=min(min(D[i-1][j]+1,D[i][j-1]+1),(A[j-1]==B[i-1]?D[i-1][j-1]:D[i-1][j-1]+1));

D[i][j]是指上图中数字区域的每个单元格的值。

完整代码如下:

#include<iostream>
#include<string>

using namespace std;

int MinEditDistance(string A,string B)
{
    int len_A = A.length();
    int len_B = B.length();
    int D[len_B+1][len_A+1];
    D[0][0]=0;
    for(int i=1;i<=len_A;i++)
    {
        D[0][i]=i;
    }
    for(int i=1;i<=len_B;i++)
    {
        D[i][0]=i;
    }
    for(int i=1;i<=len_B;i++)
    {
        for(int j=1;j<=len_A;j++)
            D[i][j]=min(min(D[i-1][j]+1,D[i][j-1]+1),(A[j-1]==B[i-1]?D[i-1][j-1]:D[i-1][j-1]+1));
    }
    return D[len_B][len_A];

}

int main()
{
    string A,B;
    cin>>A>>B;
    cout<<MinEditDistance(A,B);

}

虽说天下博客一般抄,但大家还是不要去借鉴错误的博客了。

  • 35
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
字符串相似度算法是用来比较两个字符串之间的相似程度的算法。常用的字符串相似度计算方法有编辑距离算法、余弦相似度算法、Jaccard相似度算法等。其中,编辑距离算法是一种常用的字符串相似度计算方法,它通过计算两个字符串之间的最小编辑距离来衡量它们的相似程度。编辑距离指的是将一个字符串转换成另一个字符串所需的最少操作次数,包括插入、删除、替换三种操作。 编辑距离算法的实现可以采用动态规划的方法,具体骤如下: 1. 初始化一个二维数组,数组的行数为第一个字符串长度加1,列数为第二个字符串长度加1。 2. 将第一行和第一列的值分别初始化为0到列数和0到行数。 3. 从第二行和第二列开始,遍历整个二维数组,计算每个位置的值。具体计算方法如下: - 如果第一个字符串的当前字符等于第二个字符串的当前字符,则该位置的值等于左上角位置的值。 - 否则,该位置的值等于左上角、左边、上边三个位置中的最小值加1。 4. 遍历完整个二维数组后,右下角的值即为两个字符串之间的最小编辑距离。 除了编辑距离算法,余弦相似度算法和Jaccard相似度算法也是常用的字符串相似度计算方法。余弦相似度算法通过计算两个向量之间的夹角余弦值来衡量它们的相似程度,适用于文本分类、信息检索等领域。Jaccard相似度算法则通过计算两个集合的交集与并集之间的比值来衡量它们的相似程度,适用于推荐系统、社交网络等领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值