LEVENSHTEIN DISTANCE(LD)-计算两字符串相似度算法
两字符串相似度计算方法有好多,现对基于编距的算法的相似度计算自己总结下。
简单介绍下Levenshtein Distance(LD):LD 可能衡量两字符串的相似性。它们的距离就是一个字符串转换成那一个字符串过程中的添加、删除、修改数值。
举例:
如果str1="test",str2="test",那么LD(str1,str2) = 0。没有经过转换。
如果str1="test",str2="tent",那么LD(str1,str2) = 1。str1的"s"转换"n",转换了一个字符,所以是1。
如果它们的距离越大,说明它们越是不同。
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]
最后返回的是它们的距离。怎么根据这个距离求出相似度呢?因为它们的最大距离就是两字符串长度的最大值。对字符串不是很敏感。现我把相似度计算公式定为1-它们的距离/字符串长度最大值。
LEVENSHTEIN DISTANCE(LD)-计算两字符串相似度算法
两字符串相似度计算方法有好多,现对基于编距的算法的相似度计算自己总结下。
简单介绍下Levenshtein Distance(LD):LD 可能衡量两字符串的相似性。它们的距离就是一个字符串转换成那一个字符串过程中的添加、删除、修改数值。
举例:
如果str1="test",str2="test",那么LD(str1,str2) = 0。没有经过转换。
如果str1="test",str2="tent",那么LD(str1,str2) = 1。str1的"s"转换"n",转换了一个字符,所以是1。
如果它们的距离越大,说明它们越是不同。
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]
最后返回的是它们的距离。怎么根据这个距离求出相似度呢?因为它们的最大距离就是两字符串长度的最大值。对字符串不是很敏感。现我把相似度计算公式定为1-它们的距离/字符串长度最大值。
Java代码
1.源码:
2.
3.package com.chenlb.algorithm;
4.
5./**
6. * 编辑距离的两字符串相似度
7. *
8. * @author chenlb 2008-6-24 下午06:41:55
9. */
10.public class Similarity {
11.
12. private int min(int one, int two, int three) {
13. int min = one;
14. if(two < min) {
15. min = two;
16. }
17. if(three < min) {
18. min = three;
19. }
20. return min;
21. }
22.
23. public int ld(String str1, String str2) {
24. int d[][]; //矩阵
25. int n = str1.length();
26. int m = str2.length();
27. int i; //遍历str1的
28. int j; //遍历str2的
29. char ch1; //str1的
30. char ch2; //str2的
31. int temp; //记录相同字符,在某个矩阵位置值的增量,不是0就是1
32. if(n == 0) {
33. return m;
34. }
35. if(m == 0) {
36. return n;
37. }
38. d = new int[n+1][m+1];
39. for(i=0; i<=n; i++) { //初始化第一列
40. d[i][0] = i;
41. }
42. for(j=0; j<=m; j++) { //初始化第一行
43. d[0][j] = j;
44. }
45. for(i=1; i<=n; i++) { //遍历str1
46. ch1 = str1.charAt(i-1);
47. //去匹配str2
48. for(j=1; j<=m; j++) {
49. ch2 = str2.charAt(j-1);
50. if(ch1 == ch2) {
51. temp = 0;
52. } else {
53. temp = 1;
54. }
55. //左边+1,上边+1, 左上角+temp取最小
56. d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+temp);
57. }
58. }
59. return d[n][m];
60. }
61.
62. public double sim(String str1, String str2) {
63. int ld = ld(str1, str2);
64. return 1 - (double) ld / Math.max(str1.length(), str2.length());
65. }
66.
67. public static void main(String[] args) {
68. Similarity s = new Similarity();
69. String str1 = "chenlb.blogjava.net";
70. String str2 = "chenlb.iteye.com";
71. System.out.println("ld="+s.ld(str1, str2));
72. System.out.println("sim="+s.sim(str1, str2));
73. }
74.}