字符串的编辑距离:就是一个字符变换为另一个字符的最小编辑操作
给定两个序列 X = {x1,x2,x3,…,xn},Y = {y1,y2,y3,…,ym}
找出两个子序列的最小编辑距离
解题步骤
1.假设已知最优解;dp[i][j]是Xi与Yj的编辑距离
2.求出递归式
两个序列对齐有3种对齐方式;
需要删除Xi :dp[i][j] = dp[i-1][j]+1
需要插入Yj :dp[i][j] = dp[i][j-1]+1
如果 Xi = Yj: dp[i][j] = dp[i-1][j-1];
如果 Xi!= Yj: 需要替换 dp[i][j] = dp[i-1][j-1]+1
用函数diff(i,j)表示,当Xi = Yj的时候,diff(i,j) = 0;
当Xi != Yj时侯,diff(i,j) = 1;
可写出递归式
dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+diff(i,j))
3.自底向上计算,记录最优值和最优策略
4.构造最优解dp[i][j]中记录到的就是最优解
int minEditDis(char *s1, char *s2)
{
int dp[10][10];
int len1, len2;
int i, j, k, tmp;
len1 = strlen(s1);
len2 = strlen(s2);
for (i = 0; i <= len1; i++)
{
dp[i][0] = i;
}
for (i = 0; i <= len2; i++)
{
dp[0][i] = i;
}
for (i = 1; i <= len1; i++)
{
for (j = 1; j <= len2; j++)
{
if (s1[i - 1] == s2[j - 1])
{
k = 0;
}
else
{
k = 1;
}
tmp = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
dp[i][j] = min(dp[i - 1][j - 1] + k, tmp);
}
}
return dp[len1][len2];
}
int main()
{
char s1[10];
char s2[10];
cout << "请输入字符串1:" << endl;
cin >> s1;
cout << "请输入字符串2:" << endl;
cin >> s2;
cout << minEditDis(s1,s2) << endl;
system("pause");
return 0;
}