您的位置:首页 > 其它

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

2017-11-17 15:14 405 查看
           编辑距离,又称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());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: