编辑距离问题(动态规划):
题目:
设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。
算法:
建立一个d[lenA+1][lenB+1]的表格,d[i][j]代表由前i个字符组成的子字符串转化为目的字符串前j个字符组成的字符串所需的最小字符操作数,0代表空字符串。
假设输入字符串为fxpimu 和 xwrs,对表格进行初始化后,结果如下:
那么三种操作对应三种情况:
(1)删除操作:m1 = d[i - 1][j] + 1;
(2)插入操作:m2 = d[i][j - 1] + 1;
(3)替换操作:m3 = d[i - 1][j - 1] + 1;
则
(1)如果a[i]==b[j],那么 d[i][j] = d[i - 1][j - 1];(2)如果 a[i]!=b[j],d[i][j] = min(m1, m2,m3);
依次填完表格
最小编辑距离为d[i][j]
时间复杂度为O(n2)
代码:
#include
#include
#include
using namespace std;
int Minlength(char a[100], char b[100])
{
int lenA = strlen(a);
int lenB = strlen(b);
int d[100][100] = { 0 };
int i, j, m1, m2, m3;
//初始化表格
for (j = 0; j <= lenB; j++)
{ d[j][0] = j; }
for (i = 0; i <= lenA; i++)
{ d[i][0] = i; }
for (i = 1; i <= lenA; i++)
{
for (j = 1; j <= lenB; j++)
{
if (a[i - 1] == b[j - 1])
{
d[i][j] = d[i - 1][j - 1];
}
else {
m1 = d[i - 1][j] + 1;
m2 = d[i][j - 1] + 1;
m3 = d[i - 1][j - 1] + 1;
d[i][j] = min(m1, min(m2,m3));
}
}
}
return d[lenA][lenB];}
int main()
{ ifstream in;
ofstream out;
char s1[100], s2[100];
in.open(“input.txt”, ios::in); out.open(“output.txt”, ios::out);
in >> s1 >> s2;
out << Minlength(s1, s2);
in.close();
out.close();
}