算法介绍(3) 编辑距离算法-字符串相似度

           编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。

       具体的操作方法为:
       1.修改一个字符(如把“a”替换为“b”)。
       2.增加一个字符(如把“abdd”变为“aebdd”)。
       3.删除一个字符(如把“travelling”变为“traveling”)。


       具体算法过程可按一下步骤进行:

       设 L(i,j)为使两个字符串和Ai和Bj相等的最小操作次数。

       当ai==bj时 显然 L(i,j) = L(i-1,j-1)

       当ai!=bj时 

    若将它们修改为相等,则对两个字符串至少还要操作L(i-1,j-1)次
     若删除ai或在bj后添加ai,则对两个字符串至少还要操作L(i-1,j)次
     若删除bj或在ai后添加bj,则对两个字符串至少还要操作L(i,j-1)次
     此时L(i,j) = min( L(i-1,j-1), L(i-1,j), L(i,j-1) ) + 1 

       显然,L(i,0)=i,L(0,j)=j, 再利用上述的递推公式,可以直接计算出L(i,j)值。


       构造编辑距离矩阵如下:

       

        由于L(i,0)=i,L(0,j)=j,所以有:


           计算L(1, 1),L(0, 1) + 1 == 2,L(1, 0) + 1 == 2,L(0, 0)  == 0 ,min(L(0, 1),L(1, 0),L(0, 0) ) + 1==1,因此edit(1, 1) == 1。 依次类推:


          最后得矩阵如下:


           java代码如下所示:

           

public class MinimumEditDistanceUtil {
	
	public static double MinimumDistance(String sourceStr, String targetString)
	{
		int sourceLength = sourceStr.length();
		int targetLength = targetString.length();
		sourceStr = sourceStr.toLowerCase();
		targetString = targetString.toLowerCase();
		int editMatrix[ ][ ] = new int[sourceLength][targetLength];
		
		for(int i = 0; i < sourceLength; i++)
			editMatrix[i][0] = i;
		for(int j = 0; j < targetLength; j++)
			editMatrix[0][j] = j;
		
		editMatrix[0][0] = 0;
		
		for(int i = 1; i < sourceLength; i++)
		{
			for(int j = 1; j < targetLength; j++)
			{
				if(sourceStr.charAt(i - 1) == targetString.charAt(j - 1))
					editMatrix[i][j] = editMatrix[i - 1][j - 1];
				else 
					editMatrix[i][j] = minimumValue(editMatrix[i][j - 1], editMatrix[i - 1][j], editMatrix[i - 1][j - 1]) + 1;
			}
		}
		
		
		return editMatrix[sourceLength - 1][targetLength - 1];
	}
	
	public static int minimumValue(int a, int b, int c)
	{
		int t = a <= b? a : b;
		return t <= c? t : c;
	}

	public static double stringSimilarity(String sourceStr, String targetString)
	{
		return 1 - MinimumDistance(sourceStr, targetString) / Math.max(1, sourceStr.length() + targetString.length());
//		return 1 - MinimumDistance(sourceStr, targetString) / Math.max(sourceStr.length(), targetString.length());
	}
}

猜你喜欢

转载自blog.csdn.net/BoRenLiang/article/details/78561225