题目:
定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:
1.修改一个字符(如把“a”替换为“b”);
2.增加一个字符(如把“abdd”变为“aebdd”);
3.删除一个字符(如把“travelling”变为“traveling”);
给定任意两个字符串,你是否能写出一个算法来计算它们的距离呢?
方法:
不难看出,两个字符串的距离肯定不超过它们的长度之和(我们可以通过删除操作把两个串都转化为空串)。虽然这个结论对结果没有帮助,但至少可以知道,任意两个字符串的距离都是有限的。
我们还是就住集中考虑如何才能把这个问题转化成规模较小的同样的子问题。
如果有两个串A=xabcdae和B=xfdfa,它们的第一个字符是 相同的,只要计算A[2,...,7]=abcdae和B[2,...,5]=fdfa的距离就可以了。
但是如果两个串的第一个字符不相同,那么可以进行 如下的操作(lenA和lenB分别是A串和B串的长度)。
1.删除A串的第一个字符,然后计算A[2,...,lenA]和B[1,...,lenB]的距离。
2.删除B串的第一个字符,然后计算A[1,...,lenA]和B[2,...,lenB]的距离。
3.修改A串的第一个字符为B串的第一个字符,然后计算A[2,...,lenA]和B[2,...,lenB]的距离。
4.修改B串的第一个字符为A串的第一个字符,然后计算A[2,...,lenA]和B[2,...,lenB]的距离。
5.增加B串的第一个字符到A串的第一个字符之前,然后计算A[1,...,lenA]和B[2,...,lenB]的距离。
6.增加A串的第一个字符到B串的第一个字符之前,然后计算A[2,...,lenA]和B[1,...,lenB]的距离。
在这个题目中,我们并不在乎两个字符串变得相等之后的字符串是怎样的。所以,可以将上面的6个操作合并为:
1.一步操作之后,再将A[2,...,lenA]和B[1,...,lenB]变成相字符串。
2.一步操作之后,再将A[2,...,lenA]和B[2,...,lenB]变成相字符串。
3.一步操作之后,再将A[1,...,lenA]和B[2,...,lenB]变成相字符串。
这样,很快就可以完成一个递归程序。。。然后用备忘录法!记录以及计算过的子集。
代码:
#include <iostream>
#include <string>
#define MAXN 1000
using namespace std;
int minValue(int a, int b, int c) {
if(a < b && a < c) return a;
else if(b < a && b < c) return b;
else return c;
}
int memorized[MAXN][MAXN];
int calculateStringDistance(string strA, int pABegin, int pAEnd, string strB, int pBBegin, int pBEnd) {
if(pABegin > pAEnd) {
if(pBBegin > pBEnd) {
memorized[pABegin][pBBegin] = 0;
return 0;
} else {
int temp = pBEnd - pBBegin + 1;
memorized[pABegin][pBBegin] = temp;
return temp;
}
}
if(pBBegin > pBEnd) {
if(pABegin > pAEnd) {
memorized[pABegin][pBBegin] = 0;
return 0;
} else {
int temp = pAEnd - pABegin + 1;
memorized[pABegin][pBBegin] = temp;
return temp;
}
}
if(strA[pABegin] == strB[pBBegin]) {
int temp = calculateStringDistance(strA, pABegin+1, pAEnd, strB, pBBegin+1, pBEnd);
memorized[pABegin][pBBegin] = temp;
return temp;
} else {
int t1 = calculateStringDistance(strA, pABegin+1, pAEnd, strB, pBBegin, pBEnd);
int t2 = calculateStringDistance(strA, pABegin, pAEnd, strB, pBBegin+1, pBEnd);
int t3 = calculateStringDistance(strA, pABegin+1, pAEnd, strB, pBBegin+1, pBEnd);
int temp = minValue(t1, t2, t3) + 1;
memorized[pABegin][pBBegin] = temp;
return temp;
}
}
int main() {
memset(memorized, -1, sizeof(memorized));
string strA, strB;
cin >> strA >> strB;
int ans = calculateStringDistance(strA, 0, strA.length() - 1, strB, 0, strB.length() - 1);
cout << ans << endl;
return 0;
}