最短编辑距离(Edition Distance)

题目背景:编辑距离

算法设计:DP+分类讨论

例题:51NOD1183

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

CODE:

#include 
#include 
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]=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)

你可能感兴趣的:(动态规划)