|
简单介绍下Levenshtein Distance(LD)
对于两个不同的字符串,我们有一套操作方法来把他们变得相同,具体方法为:
修改一个字符(如把“a”替换为“b”)
删除一个字符(如把“traveling”变为“travelng”)
比如对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。 无论增加还是减少“g”,我们都仅仅需要一次操作。我们把这个操作所需要的次数定义为两个字符串的距离Levenshtein Distance(LD)。
Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,用他的名字命名。不会拼读,可以叫它edit distance(编辑距离)。
Levenshtein distance可以用来:
* Spell checking(拼写检查)
* Speech recognition(语句识别)
* DNA analysis(DNA分析)
* Plagiarism detection(抄袭检测)
LD用m*n的矩阵存储距离值。算法大概过程:
1. str1或str2的长度为0返回另一个字符串的长度。
2. 初始化(n+1)*(m+1)的矩阵d,并让第一行和列的值从0开始增长。
3. 扫描两字符串(n*m级的),如果:str1 == str2[j],用temp记录它,为0。否则temp记为1。
然后在矩阵d[j]赋于d[i-1][j]+1 、d[j-1]+1、d[i-1][j-1]+temp三者的最小值。
4. 扫描完后,返回矩阵的最后一个值即d[n][m]
import java.util.*;
public class Main{
static int min(int one, int two, int three) {
int min = one;
if(two < min) {
min = two;
}
if(three < min) {
min = three;
}
return min;
}
static 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[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[j] = min(d[i-1][j]+1, d[j-1]+1, d[i-1][j-1]+temp);
}
}
return d[n][m];
}
public static void main(String[] args) {
String str1 = "chenlb.blogjava.net";
String str2 = "chenlb.javaeye.com";
System.out.println("ld="+ld(str1, str2));
}
} |
|