Levenshtein Distance(LD)-计算两字符串相似度算法关键字: 字符串 相似度 算法 ld两字符串相似度计算方法有好多,现对基于编距的算法的相似度计算自己总结下。
简单介绍下Levenshtein Distance(LD):LD 可能衡量两字符串的相似性。它们的距离就是一个字符串转换成那一个字符串过程中的添加、删除、修改数值。 举例:
如果它们的距离越大,说明它们越是不同。
Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,用他的名字命名。不会拼读,可以叫它edit distance(编辑距离)。
Levenshtein distance可以用来:
LD用m*n的矩阵存储距离值。算法大概过程:
最后返回的是它们的距离。怎么根据这个距离求出相似度呢?因为它们的最大距离就是两字符串长度的最大值。对字符串不是很敏感。现我把相似度计算公式定为1-它们的距离/字符串长度最大值。
源码:
package com.chenlb.algorithm; /** * 编辑距离的两字符串相似度 * * @author chenlb 2008-6-24 下午06:41:55 */ public class Similarity { private int min(int one, int two, int three) { int min = one; if(two < min) { min = two; } if(three < min) { min = three; } return min; } public int ld(String str1, String str2) { int d[][]; //矩阵 int n = str1.length(); int m = str2.length(); int i; //遍历str1的 int j; //遍历str2的 char ch1; //str1的 char ch2; //str2的 int temp; //记录相同字符,在某个矩阵位置值的增量,不是0就是1 if(n == 0) { return m; } if(m == 0) { return n; } d = new int[n+1][m+1]; for(i=0; i<=n; i++) { //初始化第一列 d[i][0] = i; } for(j=0; j<=m; j++) { //初始化第一行 d[0][j] = j; } for(i=1; i<=n; i++) { //遍历str1 ch1 = str1.charAt(i-1); //去匹配str2 for(j=1; j<=m; j++) { ch2 = str2.charAt(j-1); if(ch1 == ch2) { temp = 0; } else { temp = 1; } //左边+1,上边+1, 左上角+temp取最小 d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+temp); } } return d[n][m]; } public double sim(String str1, String str2) { int ld = ld(str1, str2); return 1 - (double) ld / Math.max(str1.length(), str2.length()); } public static void main(String[] args) { Similarity s = new Similarity(); String str1 = "chenlb.blogjava.net"; String str2 = "chenlb."; System.out.println("ld="+s.ld(str1, str2)); System.out.println("sim="+s.sim(str1, str2)); } }
不知sim方法中的公式是合理,个人认为差强人意思,不知javaeyer们,有没有高见,指点一二,^_^
|
|
评论
抄袭,用关键词余弦定理(向量空间模型),应该比较好.我的毕业设计就做了这方面的功能.就是用向量项. 它的缺点就是不检测结构上的相似, 当关键字相同时,把顺序倒过来,相似度还是一样.但正常情况可能满足了.