题目:许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程度。我们定义了一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:
1. 修改一个字符(如把“a”替换为“b”)。
2. 增加一个字符(如把“abdd”变为“aebdd”)。
3. 删除一个字符(如把“travelling”变为“traveling”)。
比如,对于“abcdefg”和“abcdef”两个字符串来说, 我们认为可以通过增加/减少一个“g”的方式来达到目的。上面的两种方案,都仅需要一次操作。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于“距离+1”的倒数。也就是说,“abcdefg”和“abcdef”的距离为1,相似度为1 / 2 = 0.5。
给定任意两个字符串,你是否能写出一个算法来计算出它们的相似度呢?
解法:在这个题目中,我们并不在乎两个字符串变得相等之后的字符串是怎样的。所以
1. 一步操作之后,再计算A[2, …, lenA]和B[1, …, lenB]的距离。
2. 一步操作之后,再计算A[1, …, lenA]和B[2, …, lenB]的距离。
3. 一步操作之后,再计算A[2, …, lenA]和B[2, …, lenB]的距离。
这样,很快就可以完成一个递归程序:
/*
计算字符串最小距离
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *s1="abcdef";
char *s2="aecdedf";
int minvalue(int d1,int d2,int d3)
{
int min;
min=d1;
if(d2<min)
{
min=d2;
}
if(d3<min)
{
min=d3;
}
return min;
}
int CalculateStringDistance(char s1[],int b1,int e1,char s2[],int b2,int e2)
{
int d1,d2,d3;
if(b1>e1) //串s1比较完毕
{
return e2-b2+1;
}
if(b2>e2) //串s2比较完毕
{
return e1-b1+1;
}
if(s1[b1]==s2[b2]) //当前字母相同,后移一个字母对于余串进行比较
{
CalculateStringDistance(s1,b1+1,e1,s2,b2+1,e2);
}
else
{
d1=CalculateStringDistance(s1,b1,e1,s2,b2+1,e2); //等价于删除串s2首字母
d2=CalculateStringDistance(s1,b1+1,e1,s2,b2,e2); //等价于删除串s1首字母
d3=CalculateStringDistance(s1,b1+1,e1,s2,b2+1,e2); //等价于删除串s1和串s2的首字母
return minvalue(d1,d2,d3)+1; //由于删除操作距离增加1
}
}
int main(void)
{
int dis,len1,len2;
len1=strlen(s1);
len2=strlen(s2);
dis=CalculateStringDistance(s1,0,len1-1,s2,0,len2-1);
printf("The distance between \n\"%s\"\n and\n\"%s\"\nis %d.\n\n",s1,s2,dis);
system("pause");
return 0;
}编程之美---计算字符串的相似度,布布扣,bubuko.com
原文:http://blog.csdn.net/cjc211322/article/details/21743247