码迷,mamicode.com
首页 > 其他好文 > 详细

字符串的编辑距离

时间:2015-08-12 16:44:27      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:

字符串的相似度定义为:将一个字符串转换成另外一个字符串时需要付出的代价。转换可以采用插入、删除和替换三种编辑方式,因此转换的代价就是对字符串的编辑次数。

作为对比采用两种方式:递归算法和动态规划算法

朴素递归方式实现:朴素递归方式很清晰,很简洁,但是时间复杂度很高

public static int editDistance(String srcStr,String destSrc,int srcStart,int descStart)
	{
		//如果任意一个字符串结束,则返回
		if((srcStr.length()-srcStart)==0 || (destSrc.length()-descStart)==0)
		{
			return Math.abs((srcStr.length()-srcStart)-(destSrc.length()-descStart));
		}
		if(srcStr.charAt(srcStart)==destSrc.charAt(descStart))
		{
			return editDistance(srcStr,destSrc,srcStart+1,descStart+1);
		}
		
		int edIns=editDistance(srcStr,destSrc,srcStart,descStart+1)+1;//插入字符
		int edDel=editDistance(srcStr,destSrc,srcStart+1,descStart)+1;//删除字符
		int edRep=editDistance(srcStr,destSrc,srcStart+1,descStart+1)+1;//替换字符
		int min1=edIns>edDel?edDel:edIns;
		return min1>edRep?edRep:min1;
	}

 现在考虑用动态规划的方法进行改进。首先定义出问题的状态,从状态转换关系开始定义阶段和子问题的递推关系。

假设如果将问题定义为求解source的[1.....n]个字符转换为target[1.....m]个字符所需要的最少编辑次数(编辑距离),则子问题就可以定义为将source[1......i]个字符转换为target[1......j]个字符所需要的最少编辑次数,这就是本问题的最优子结构,因此我们将状态定义为从子串source[1......i]到子串target[1......j]之间的编辑距离。

朴素递归的方法之所以时间复杂度很高,是因为大量的状态是重复计算的。接下来引入备忘录概念,用一个二维表记录每个状态的值,递归过程中优先查找表。

/*改进的带有备忘录的递归方法*/
	public static int editDistanceBetter(String srcStr,String destSrc,int srcStart,int descStart,TagMemoRecord[][] tRecords)
	{
		//首先查表
		if(tRecords[srcStart][descStart].refCount!=0)
		{
			tRecords[srcStart][descStart].refCount++;
			return tRecords[srcStart][descStart].distance;
		}
		int distance=0;
		//如果任意一个字符串结束,则返回
		if((srcStr.length()-srcStart)==0 || (destSrc.length()-descStart)==0)
		{
			distance=Math.abs((srcStr.length()-srcStart)-(destSrc.length()-descStart));
		}
		else if(srcStr.charAt(srcStart)==destSrc.charAt(descStart))
		{
			distance=editDistance(srcStr,destSrc,srcStart+1,descStart+1);
		}
		else 
		{
			int edIns=editDistance(srcStr,destSrc,srcStart,descStart+1)+1;//插入字符
			int edDel=editDistance(srcStr,destSrc,srcStart+1,descStart)+1;//删除字符
			int edRep=editDistance(srcStr,destSrc,srcStart+1,descStart+1)+1;//替换字符
			int min1=edIns>edDel?edDel:edIns;
			distance= min1>edRep?edRep:min1;
		}
		tRecords[srcStart][descStart].distance=distance;
		tRecords[srcStart][descStart].refCount=1;
		return distance;
		
	}

 

class TagMemoRecord
{
	int distance;
	int refCount;
	public TagMemoRecord() {
		this.distance=-1;
		this.refCount=0;
	}
}

 

字符串的编辑距离

标签:

原文地址:http://www.cnblogs.com/xtsylc/p/4722901.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!