我们的目的在于判断字符串的相似程度。我们定义了一套操作方法来把两个不同的字符串变得相同,具体的操作方法为:
1、修改一个字符(如吧“a”替换为“b”);
2、增加一个字符(如把“abdd”变为“aebdd”);
3、删除一个字符(如把“travelling”变为“traveling”)。
比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。上面的两种方案,都仅需要一次操作。把这个操作所需要的次数定义为两个字符串的距离,而相似程度等于“距离+1”的倒数。也就是说,“abcdefg”和“abcdef”的距离为1,相似度为1/2=0.5。
给定任意两个字符串,写出一个算法来计算出他们的相似度:
两个字符串的距离肯定不超过他们的长度之和(我们可以通过删除操作把两个串转化为空串)。虽然这个结论对结果没有帮助,但至少可以知道,任意两个字符串的距离都是有限的。
考虑如何才能把这个问题转化成规模较小的同样的问题。
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[1,....,lenA]和B[2,....,lenB]变成相同字符串。
3、一步操作之后,再将A[2,....,lenA]和B[2,....,lenB]变成相同字符串。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;int minValue(int a,int b,int c) //计算3个数中的最小值
{
int tmp=min(a,b);
return min(tmp,c);
}
//计算两个字符串的距离
//最好用动态规划的方法记录下各值,这样就可以避免重复计算的问题,动态规划算法有待进一步实现
int CalculateStringDistance(string strA,int pABegin,int pAEnd, string strB,int pBBegin,int pBEnd)
{
if(pABegin>pAEnd)
{
if(pBBegin>pBEnd) return 0;
else return pBEnd-pBBegin+1;
}
if(pBBegin>pBEnd)
{
if(pABegin>pAEnd) return 0;
else return pAEnd-pABegin+1;
}
if(strA[pABegin]==strB[pBBegin])
{
return CalculateStringDistance(strA,pABegin+1,pAEnd,strB,pBBegin+1,pBEnd);
}
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);
return minValue(t1,t2,t3)+1;
}
}int main()
{
string str1,str2;
cout<<"请输入两个字符串"<<endl;
cin>>str1>>str2;
int a,b;
a=str1.size();
b=str2.size();
cout<<"a=="<<a<<endl;
cout<<"b=="<<b<<endl;
cout<<"两字符串的距离为:"<<CalculateStringDistance(str1,0,a,str2,0,b);
return 0;
}
个人觉得这个跟算法中的求两个序列的最长公共子序列有点像。