问题描述
对于给定的两个字符串,可以进行增加、减少或者修改一个字符的方式使一个字符串等于另一个字符串,把需要操作的次数定义为两个字符串的距离,相似度等于“距离+1”的倒数。
分析求解
两个字符串A和B,下标范围为[aBegin,aEnd]和[bBegin,bEnd]
如果第一个字符相等,则不作处理,只需计算A[2,aEnd]和B[2,bEnd]的距离
如果不相等,可以做以下处理
删除A的第一个字符,然后计算A[2,aEnd]和B[1,bEnd]的距离。
删除B的第一个字符,然后计算A[1,aEnd]和B[2,bEnd]的距离。
修改A的第一个字符为B的第一个字符,然后计算A[2,aEnd]和B[2,bEnd]的距离。
修改B的第一个字符为A的第一个字符,然后计算A[2,aEnd]和B[2,bEnd]的距离。
添加A的第一个字符到B的第一个字符之前,然后计算A[2,aEnd]和B[1,bEnd]的距离。
添加B的第一个字符到A的第一个字符之前,然后计算A[1,aEnd]和B[2,bEnd]的距离。
但是我们最终关注的问题是怎样求得两个字符串的距离,也就是说我们只要知道通过一步操作就可以将问题简化成规模更小的问题就可以,没有必要实施这个操作。
那么上面6个操作就可以合并为下面3个操作
一步操作之后,再处理A[1,aEnd]和B[2,bEnd]。
一步操作之后,再处理A[2,aEnd]和B[1,bEnd]。
一步操作之后,再处理A[2,aEnd]和B[2,bEnd]。
代码实现
//*End代表的是要比较的字符串的最后一个字符的下一个位置
int calculate(char *strA, int aBegin, int aEnd, char *strB, int bBegin, int bEnd)
{
if(aBegin>=aEnd)
{
if(bBegin>=bEnd)
return 0;
else
return bEnd-bBegin;
}
if(bBegin>=bEnd)
{
if(aBegin>=aEnd)
return 0;
else
return aEnd-aBegin;
}
if(strA[aBegin]==strB[bBegin])
{
return calculate(strA,aBegin+1,aEnd,strB,bBegin+1,bEnd);
}
else
{
int n1 = calculate(strA,aBegin+1,aEnd,strB,bBegin,bEnd);
int n2 = calculate(strA,aBegin,aEnd,strB,bBegin+1,bEnd);
int n3 = calculate(strA,aBegin+1,aEnd,strB,bBegin+1,bEnd);
//求最小值+1
return min(n1,n2,n3) + 1;
}
}
参考书籍:《编程之美》