/**
Levenshtein distance最先是由俄國科學家Vladimir Levenshtein在1965年發明,用他的名字命名。不會拼讀,可以叫它edit distance(編輯距離)。
Levenshtein distance可以用來:
Spell checking(拼字檢查)
Speech recognition(語句識別)
DNA analysis(DNA分析)
Plagiarism detection(抄襲檢測)
LD用m*n的矩陣儲存距離值。演算法大概過程:
str1或str2的長度為0返回另一個字串的長度。
初始化(n+1)*(m+1)的矩陣d,並讓第一行和列的值從0開始增長。
掃描兩字串(n*m級的),如果:str1[i] == str2[j],用temp記錄它,為0。否則temp記為1。然後在矩陣d[i][j]賦於d[i-1][j]+1 、d[i][j-1]+1、d[i-1][j-1]+temp三者的最小值。
掃描完後,返回矩陣的最後一個值即d[n][m]
*/
public class LD
{
/**
* 計算向量距離
* Levenshtein Distance(LD)
* @param str1 str1
* @param str2 str2
* @return ld
*/
public int ld(String str1, String str2)
{
//Distance
int [][] d;
int n = str1.length();
int m = str2.length();
int i; //iterate str1
int j; //iterate str2
char ch1; //str1
char ch2; //str2
int temp;
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++)
{
ch1 = str1.charAt(i - 1);
//match str2
for (j = 1; j <= m; j++)
{
ch2 = str2.charAt(j - 1);
if (ch1 == ch2)
{
temp = 0;
}
else
{
temp = 1;
}
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + temp);
}
}
return d[n][m];
}
private int min(int one, int two, int three)
{
int min = one;
if (two < min)
{
min = two;
}
if (three < min)
{
min = three;
}
return min;
}
/**
* 計算相似性
* @param str1 str1
* @param str2 str2
* @return sim
*/
public double sim(String str1, String str2)
{
int ld = ld(str1, str2);
return 1 - (double) ld / Math.max(str1.length(), str2.length());
}
/**
* 測試
* @param args
*/
public static void main(String[] args)
{
LD ld = new LD();
double num = ld.sim("xie", "xies");
System.out.println(num);
}
}
本人試了一下,既可以計算一個字串,也可以計算一個句子,完全相等的時候相似性為1,
感覺挺好用的
轉載自:http://xieruilin.iteye.com/blog/743342