计算两个字符串的距离

来源:互联网 发布:js获取文本框输入的值 编辑:程序博客网 时间:2024/04/27 17:58


题目描述:

计算字符串的相似度

许多程序会大量使用字符串。对于不同的字符串,希望能够有办法判断其相似程度。定义了如下方法来把两个不同的字符串变得相同,具体的操作方法为:

1. 修改一个字符(如把"a"替换为"b")

2. 增加一个字符(如把"abc"变换为"aabc")

3. 删除一个字符(如把"abc"变换为"bc")

比如,对于”abc”和”bc”两个字符串来说,可以通过增加/删除一个”a”的方式来达到目的。上面的两种方案,都仅需要一次操作。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于”距离+1”的倒数。也就是说,”abc”和”bc”的距离为1,相似度为1/(1+1)=0.5。

给定任意两个字符串,写出一个算法来计算它们的相似度。

分析:

要计算相似度,首先要得到两个字符串的距离。而可以肯定的是,任意两个字符串的距离都是有限的(两个字符串的距离肯定不超过他们的长度之和,至少我们可以通过删除操作把两个字符串都转化为空串。)

如果有两个字符串A和B,如果它们的第一个字符是相同的,只要计算A[2,…,lenA]和B[2,…,lenB]的距离。如果它们的第一个字符是不相同的,那么可以进行如下的操作。

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. 增加A的第一个字符到B第一个字符之前,然后计算A[2,…,lenA]和B[1,…,lenB]的距离;

6. 增加B的第一个字符到A第一个字符之前,然后计算A[1,…,lenA]和B[2,…,lenB]的距离。

从上面的分析可以看出,如果A和B的第一个字符不相同,那么可以不管之后会变成什么样,就可以把上面的6个操作合并成下面3个。

1. 一步操作之后,计算A[2,…,lenA]和B[1,…,lenB]的距离。

2. 一步操作之后,计算A[1,…,lenA]和B[2,…,lenB]的距离。

3. 一步操作之后,计算A[2,…,lenA]和B[2,…,lenB]的距离。 

这样就可以得到一个递归程序:

递归出口是:如果某一次操作后,A串为空,再判断B串;如果B串也为空,那么返回0;如果B串不为空,那么返回B串剩下的长度。

                 如果某一次操作后,B串为空,那么判断A串;如果A串也为空,那么返回0;如果A串不为空,则返回A串剩余的长度。

代码如下:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>//返回三个数中最小的一个int GetMin(int i, int j, int k){return ((i < j) ? (i < k ? i : k):(j < k ? j : k));}int CalculateStringDistance(char *str1,int Abegin,int Aend,char *str2,int Bbegin,int Bend){int distance1,distance2,distance3;assert(str1!=NULL&&str2!=NULL);if(Abegin > Aend)  //某次操作后,A是空串{if(Bbegin > Bend)   //B也是空串return 0;else                //A是空串,B不是空串return Bend - Bbegin + 1;   }if(Bbegin > Bend)  {if(Abegin > Aend)return 0;elsereturn Aend - Abegin + 1;}if(str1[Abegin] == str2[Bbegin])   //A、B都不是空串,且首字符相同{return CalculateStringDistance(str1,Abegin+1,Aend,str2,Bbegin+1,Bend);}else  //合并后的三种操作{distance1=CalculateStringDistance(str1,Abegin +1,Aend,str2,Bbegin,Bend);     //一步操作之后,计算A[2,…,lenA]和B[1,…,lenB]的距离distance2=CalculateStringDistance(str1,Abegin,Aend,str2,Bbegin +1,Bend);     //一步操作之后,计算A[1,…,lenA]和B[2,…,lenB]的距离distance3=CalculateStringDistance(str1,Abegin +1,Aend,str2,Bbegin +1,Bend);  //一步操作之后,计算A[2,…,lenA]和B[2,…,lenB]的距离//return min(distance1,distance2,distance3);  //注意,这里返回的是  min+1return min(distance1,distance2,distance3) +1;}}void main(){char str1[1000];char str2[1000];int length1;int length2;int distance;float similar;gets(str1);gets(str2);length1=strlen(str1);length2=strlen(str2);distance=CalculateStringDistance(str1,0,length1-1,str2,0,length2-1);printf("字符串%s与%s的距离是:%d\n",str1,str2,distance);similar=1/(float)(1+distance);printf("字符串%s与%s的相似度:%f\n",str1,str2,similar);}

0 0