编辑距离

例题:

http://www.51nod.com/Challenge/Problem.html#problemId=1183

编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如将kitten一字转成sitting:
sitten (k->s)
sittin (e->i)
sitting (->g)
所以kitten和sitting的编辑距离是3。俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
给出两个字符串a,b,求a和b的编辑距离。
 

输入

第1行:字符串a(a的长度 <= 1000)。
第2行:字符串b(b的长度 <= 1000)。

输出

输出a和b的编辑距离

输入样例

kitten
sitting

输出样例

3
分析:

  设字符串S和T的长度分别为m和n, 两者的编辑距离表示为dp[m][n]. 则对序列进行操作时存在以下几种情况:

a,   当S和T的末尾字符相等时, 不需要增加计数. 则满足条件: dp[m][n] = dp[m - 1][n - 1].

b,   当S和T的末尾字符不相等时, 则需要对两者之一的末尾进行编辑, 相应的计数会增加1:.
 ,      对S或T的末尾进行修改, 以使之与T或S相等, 则此时dp[m][n] = dp[m - 1][n - 1] + 1;
        删除S末尾的元素, 使S与T相等, 则此时dp[m][n] = dp[m - 1][n] + 1;
        删除T末尾的元素, 使T与S相等, 则此时dp[m][n] = dp[m][n - 1] + 1;
 ,      在S的末尾添加T的尾元素, 使S和T相等, 则此时S的长度变为m+1, 但是此时S和T的末尾元素已经相等, 只需要比较S的前m个元素与T的前n-1个元素, 所以满足dp[m][n] = dp[m][n - 1] + 1;
        在T的末尾添加S的尾元素, 使T和S相等, 此时的情况跟b4相同, 满足dp[m][n] = dp[m - 1][n] + 1;


比较特殊的情况是, 当S为空时, dp[0][n] = n; 而当T为空时, dp[m][0] = m; 这个很好理解, 例如对于序列""和"abc", 则两者的最少操作为3, 即序列""进行3次插入操作, 或者序列"abc"进行3次删除操作.
还有一点就是dp[0][0]=0;

综上所述  递推公式就是:   dp[i][j]=dp[i-1][j-1](S的第i项和t的第j项相等时)

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

AC代码:

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring> 
using namespace std;
char a[1000+10];
char b[1000+10];
int dp[1000+10][1000+10]; 
int main(){
    scanf("%s %s",a+1,b+1);
    a[0]=b[0]='0';
    int n=strlen(a);
    int m=strlen(b);
    for(int i=1;i<=n;i++)
        dp[0][i]=i;
     for(int i=1;i<=m;i++)
         dp[i][0]=i;
    dp[0][0]=0;
//以上为初始化,,以下为核心部分
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]; else { int temp=min(dp[i][j-1]+1 ,dp[i-1][j]+1 ); dp[i][j]=min(temp,dp[i-1][j-1]+1 ); } } cout<<dp[n][m]<<endl; return 0; }
原文地址:https://www.cnblogs.com/Accepting/p/11288470.html