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

原创 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;
}
上面的递归程序,有什么地方需要改进呢?在递归的过程中,有些数据被重复计算了。

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


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

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

《编程之美》- 3.3 - 计算字符串相似度 即 最小编辑距离问题

题目 3.3计算字符串的相似度 许多程序会大量使用字符串,对于不同的字符串,我们希望能够有办法判断其相似程度。定义下列操作方法使得两个不同的字符串变得相同: 修改一个字符(如把‘a’改为...
  • fly_yr
  • fly_yr
  • 2016年05月24日 20:07
  • 783

《编程之美》读书笔记: 3.3 计算字符串的相似度

《编程之美》读书笔记11: 3.3 计算字符串的相似度 很经典的可使用动态规划方法解决的题目,和计算两字符串的最长公共子序列相似。 设Ai为字符串A(a1a2a3 … am)的前i个字符(即为a1...
  • a724470522
  • a724470522
  • 2012年02月23日 21:13
  • 191

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

使用递归实现,但是计算了重复的子问题,所以采用记忆化方法,将子问题的解保存在一个数组里。 #include #include #include #include using namespac...
  • xiaozhuaixifu
  • xiaozhuaixifu
  • 2013年07月17日 21:13
  • 757

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

问题描述: 许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的 字符串变得相同,具体的操作方法为:   1.修改一个字符(如把“a...
  • yuhan_9204
  • yuhan_9204
  • 2015年03月06日 11:45
  • 225

编程之美读书笔记_3.3_计算字符串的相似度

3.3_计算字符串的相似度 和计算两字符串的最长公共子序列相似。设Ai为字符串A(a1a2a3 … am)的前i个字符(即为a1,a2,a3 … ai)设Bj为字符串B(b1b2b3 … bn)的前j...
  • flyinghearts
  • flyinghearts
  • 2010年05月19日 00:13
  • 4238

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

 把两个字符串变成相同的基本操作定义如下:1.     修改一个字符(如把 a 变成 b)2.     增加一个字符 (如 abed 变成 abedd)3.     删除一个字符(如 jackbllo...
  • djyangmaowei
  • djyangmaowei
  • 2010年05月10日 14:37
  • 1003

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

Ref:http://www.cnblogs.com/yujunyong/articles/2004724.html 许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我...
  • yeepom
  • yeepom
  • 2013年03月23日 13:22
  • 593

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

package structure; /** * 计算字符串的相似度:对于两个不同的字符串,转成相同的字符串要几步(t) 1/(t+1)就是要求的字符串的相似度 * * * 思路:如果a...
  • jiang_bing
  • jiang_bing
  • 2012年10月25日 09:52
  • 311

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

1、题目:给定任意两个字符串, 计算他们的相似度。
  • woshibendangao
  • woshibendangao
  • 2014年08月18日 14:28
  • 513
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:编程之美读书笔记-计算字符串的相似度
举报原因:
原因补充:

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