编程之美---计算字符串的相似度

题目:许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程度。我们定义了一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:
        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;
}
编程之美---计算字符串的相似度_第1张图片

你可能感兴趣的:(编程之美,字符串相似度)