编辑距离

来源:互联网 发布:如何防止sql攻击 编辑:程序博客网 时间:2024/05/16 06:41
给定两个字符串S和T,对于T我们允许三种操作:
(1) 在任意位置添加任意字符(2) 删除存在的任意字符(3) 修改任意字符 
问最少操作多少次可以把字符串T变成S? 
例如: S=  “ABCF”   T = “DBFG”
那么我们可以
(1) 把D改为A(2) 删掉G(3) 加入C
所以答案是3。
分析: 这个最少的操作次数,通常被称之为编辑距离。“编辑距离”一次本身具有最短的意思在里面。因为题目有“最短”这样的关键词,首先我们想到的是BFS。是的,当S的距离为m, T的距离为n的时候,我们可以找到这样的操作次数的界限:
(1) 把T中字符全删了,再添加S的全部字符,操作次数m + n。(2) 把T中字符删或加成m个,再修改 操作次数最多 |n – m| + m。虽然,我们找到了这样的上界,BFS从实际角度并不可行,因为搜索空间是指数的,这取决于S中的字符种类——具体的数量级不好估计。
最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
输入
第1行:字符串a(a的长度 <= 1000)。第2行:字符串b(b的长度 <= 1000)。

输出

输出a和b的编辑距离

输入示例

kittensitting

输出示例

3

请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
不同语言如何处理输入输出,请查看下面的语言说明。
题解:dp[i][j]表示S前i个和T前j个要扣的最少分。
1:当S[i]和T[j]相同时,那么这种情况下最少要扣的分数是dp[i-1][j-1];
2:当S[i]和T[j]不同时,那么这种情况下最少要扣的分数是 dp[i-1][j-1]+1和(S的前i个和T的前j-1个已经对齐)dp[i][j-1]+1和
(S的前i-1个和T的前j个已经对齐)dp[i-1][j]+1的最小值;此时得出状态转移方程,实现代码对你来说肯定轻而易举啦。(此种方法复杂度O(n^2))
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int dp[1010][1010];int main(){    char a[1010];    char b[1010];    scanf("%s %s",a+1,b+1);    a[0]=b[0]='0';    int l1=strlen(a)-1;    int l2=strlen(b)-1;    for(int i=0;i<=l1;i++){        dp[i][0]=i;    }    for(int i=0;i<=l2;i++)    dp[0][i]=i;    for(int i=1;i<=l1;i++){        for(int j=1;j<=l2;j++){            if(a[i]!=b[j]){                dp[i][j]=min(dp[i-1][j]+1,min(dp[i-1][j-1]+1,dp[i][j-1]+1));            }else{                dp[i][j]=dp[i-1][j-1];            }        }    }    printf("%d",dp[l1][l2]);    return 0;}


 
原创粉丝点击