编程之美读书笔记-计算字符串的相似度

原创 2016年08月31日 12:22:14

题目:许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程度。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:
1.修改一个字符(如把a替换为b);
2.增加一个字符(如把abdd变为aebdd);
3.删除一个字符(如把travelling变为traveling)。
比如,对于abcdefg和abcdef两个字符串来说,我们认为可以通过增加/减少一个g的方式来达到目的。上面的两种方案,都仅需要一次操作。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于距离+1的倒数。也就是说,abcdefg和abcdef的距离为1,相似度 为1/2=0.5。给定任意两个字符串,你是否能写出一个算法来计算它们的相似度呢?
解析:不难看出,两个字符串的距离肯定不超过它们的长度之和(我们可以通过删除操作把两个串都转化为空串)。虽然这个结论对结果没有帮助,但至少可以知道,任意两个字符串的距离都是有限的。考虑如何才能把这个问题转化成规模较小的同样的子问题。如果有两个串A=xabcdae和B=xfdfa,它们的第一个字符是相同的,只要计算A[2,...,7]=abcdae和B[2,...,5]=fdfa的距离就可以了。但是如果两个串的第一个字符不相同,那么可以进行 如下的操作(lenA和lenB分别是A串和B串的长度)。
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[2,...,lenA]和B[2,...,lenB]变成相字符串。
3.一步操作之后,再将A[1,...,lenA]和B[2,...,lenB]变成相字符串。
这样,很快就可以完成一个递归程序。

#include <string> 
#include <iostream> 
#include <algorithm>  
using namespace std;

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, pAEnd, strB, pBBegin + 1, pBEnd);
		int t2 = calculateStringDistance(strA, pABegin + 1, pAEnd, strB, pBBegin, pBEnd);
		int t3 = calculateStringDistance(strA, pABegin + 1, pAEnd, strB, pBBegin + 1, pBEnd);
		return min(min(t1, t2), t3) + 1;
	}
}

int main()
{
	string A = "xabcde";
	string B = "wxabcds";
	cout << calculateStringDistance(A, 0, A.length() - 1, B, 0, B.length()-1) << endl;
	return 0;
}
上面的递归程序,有什么地方需要改进呢?在递归的过程中,有些数据被重复计算了。

可以看到,圈中的两个子问题被重复计算了。为了避免这种不必要的重复计算,可以把子问题计算后的解存储起来。


版权声明: 举报

相关文章推荐

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

转 问题: 1. 计算两个字符串的最长公共子序列(LCS),且公共子序列在字符串中不需要是连续的。 2. 计算两个字符串的距离,完全相同的字符串距离为0,可以通过修改一个...

编程之美3.3 计算字符串的相似度(我的失败思路)

题干 许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为: 修改一个字符(如把“a”替换为“b”);...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

编程之美:计算两个字符串的相似度---动态规划实现

问题描述: 把两个字符串变成相同的基本操作定义如下: 1.     修改一个字符(如把 a 变成 b) 2.     增加一个字符 (如 abed...

[编程之美] PSet3.3 计算字符串的相似度

问题描述:

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

题目: 许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:   1.修改一个字符(如把“a”替换为...

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

编程之美---计算字符串的相似度       在比较字符串是否相同时,我们经常要考虑两个字符串的编辑距离,所谓编辑距离就是通过修改、删除、插入等三种操作使两个字符串相等所需要的步数。字符串的相似度定义...

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

题目:许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为: 1.修改一个字符(如把“a”替换为“b”)...

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

许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:   1.修改一个字符(如把“a”替换为“b”...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)