最短编辑距离(Edition Distance)

本文详细介绍了一种求解字符串间编辑距离的动态规划算法,并通过一个具体的实现案例进行讲解。介绍了编辑距离的概念,包括插入、删除和替换三种基本操作,以及如何通过动态规划找到这些操作的最小组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目背景:编辑距离

算法设计:DP+分类讨论

例题:51NOD1183

这是一个模板,但模板不是万能的,现在我们来看它的具体算法:

CODE:

#include <iostream>
#include <string>
using namespace std;
string s1,s2;
int dp[1010][1010],len1,len2;
int main()
{
    while(cin>>s1>>s2)
    {
        len1=s1.size();
        len2=s2.size();
        for(int i=1;i<=len1;++i)
            for(int j=1;j<=len2;++j)
                dp[i][j]=0;
        int flag;
        for(int i=0;i<=len1;++i)    dp[i][0]=i;
        for(int i=0;i<=len2;++i)    dp[0][i]=i;
        for(int i=1;i<=len1;++i)
            for(int j=1;j<=len2;++j)
            {
                 if(s1[i-1]==s2[j-1])
                    flag=0;
                else
                    flag=1;
                int tmp=min(dp[i-1][j]+1,dp[i][j-1]+1);
                dp[i][j]=min(dp[i-1][j-1]+flag,tmp);
                //dp[i][j]=max(dp[i-1][j-1]+flag,dp[i-1][j]+1,dp[i-1][j-1]+1);/**/
            }
        /*for(int i=1;i<=len1;++i)
        {
            for(int j=1;j<=len2;++j)
                cout<<dp[i][j]<<" ";
            cout<<endl;
        }*/
        cout<<dp[len1][len2]<<endl;
    }
}
/*
kitten
sitting
*/

关于状态转移方程:

dp[i][j]=min(dp[i-1][j-1]+flag,dp[i-1][j]+1,dp[i][j+1]+1);

flag=\left\{\begin{matrix} 0,s1[i]=s2[j]\\ 1,s1[i]!=s2[j] \end{matrix}\right.

现在来解释这个状态转移方程:

1.我们已经知道串s1,串s2之间修改有三种操作:

一、修改:这对应于: dp[i-1][j-1]+flag

二、删除:对应与:dp[i-1][j]+1

三:加入:把s2加入到s1的前面:dp[i][j+1]+1

2.因为我们是要求最小的编辑距离,所以转移的时候,要比较这三种操作的最小值,

3.修改是什么意思:我们要看s1的第 i 个字符要不要修改成s2的第 j 个字符,如果这两个字符是相同的,那么就要改0个字符,否则,就要改 1 个字符,所以,这个 flag 就是 要修改的字符的个数的意思

4.什么是删除?这里我们要把s1的第i个字符给删除,那么这个时候的编辑距离就是dp[i-1,j]+1距离

5.同理,我们把s2的第 j 个字符加入到 s1 的 第 i 个字符前面,那么这份时候的编辑距离就是dp[i,j-1]的距离le

6.之后,只要比较这三种操作哪一种花费最小即可。

初始化数组的问题:

 dp[0][0]\rightarrow dp[0][i]=i (i<=lens1), dp[0][0]\rightarrow dp[i][0]=i (i<=lens2)

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值