动态规划——模型之:字符串相似度/编辑距离(edit distance)

首先建一个数组记忆化储存两个字符串之间的编辑距离,我命名为ed[ ][ ]

其次就是初始化这个用于记忆化的数组ed,因为既然是动态规划,逐本溯源,一定会由边界条件;

(这里我命名第一个字符串为source,设其字符串长度为n;第二个字符串名字为target,设其字符串长度为m)

由于这是一个意义为两个字符串间距离比较的数组(这个数组记录了source这个串长度由0到n形成的每个子串与target这个串长度由0到m之间形成的每个子串之间的编辑距离):那么,边界条件必然为

source长度为0时,source与target之间的编辑距离就是此时target的子串的长度,

以及,  target长度为0时,source与target之间的编辑距离就是此时source的子串的长度.

到现在为止,初始化已经完事了

接下来进行递归:

ed[i][j]会有两种情况:

1.source[i]==target[j]          此时ed[i][j]=ed[i-1][j-1]

2.source[i] != target[j]

-------此时的ed[i][j]可能是由三种情况递推而来的:

1)由ed[i-1][j-1]通过将source[i](或是:将target[j])变换为target[j](变换为source[i])得来的

          故,此种递推方程为ed[i][j]=ed[i-1][j-1]+1

2)由ed[i-1][j]通过将source[i]删去(由于source[i] != target[j],所以把不一样的那个字符( 即 source[i]  )删去)得来的             

          故,此种递推方程为ed[i][j]=ed[i-1][j]+1

3)由ed[i][j-1]通过将target[j]删去(由于source[i] != target[j],所以把不一样的那个字符( 即 target[j]  )删去)得来的             

          故,此种递推方程为ed[i][j]=ed[i][j-1]+1

现在我们递推关系也捋清楚了,接下来上代码吧

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<string>

using namespace std;
#define maxx 20
int ed[maxx+5][maxx+5];
int ED(string source,string target)
{
    int n=source.length();
    int m=target.length();
    if(m==0)    return n;
    if(n==0)    return m;
    memset(ed,0,sizeof(ed));
    for(int i=0;i<=n;i++)
    {
        ed[i][0]=i;
    }
    for(int i=0;i<=m;i++)
    {
        ed[0][i]=i;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            int cost;
            if(source[i-1]==target[j-1])
                cost=0;
            else
                cost=1;
            ed[i][j]=min(  ed[i-1][j-1]+cost,min( ed[i-1][j]+1 , ed[i][j-1]+1 )  );
        }
    }
    return ed[n][m];
}

int main()
{
    string s,t;//s:source   t:target
    while(cin>>s>>t)
    {
        cout<<ED(s,t)<<endl;
    }

    return 0;
}

 说实在的,可能是大佬们都觉得这个比较简单,网上很多都是一笔带过,哎,,,,

那我就写的细致点吧,也当是自己再捋顺一遍思路了

猜你喜欢

转载自blog.csdn.net/qq_41764621/article/details/81459740