编辑距离:
1、定义-->两个字符串,其中一个相对于另一个经过增删改操作的最少编辑次数
2、算法过程-->
- str1或str2的长度为0返回另一个字符串的长度。 if(str1.length==0) return str2.length; if(str2.length==0) return str1.length;
- 初始化(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]即是它们的距离。
3、举例-->以“ivan1”和“ivan2“两字符串为例
1、第一行和第一列的值从0开始增长
i | v | a | n | 1 | ||
0 | 1 | 2 | 3 | 4 | 5 | |
i | 1 | |||||
v | 2 | |||||
a | 3 | |||||
n | 4 | |||||
2 | 5 |
2、i列值的产生 Matrix[i - 1, j] + 1 ; Matrix[i, j - 1] + 1 ; Matrix[i - 1, j - 1] + t
i | v | a | n | 1 | ||
0+t=0 | 1+1=2 | 2 | 3 | 4 | 5 | |
i | 1+1=2 | 取三者最小值=0 | ||||
v | 2 | 依次类推:1 | ||||
a | 3 | 2 | ||||
n | 4 | 3 | ||||
2 | 5 | 4 |
3、V列值的产生
i | v | a | n | 1 | ||
0 | 1 | 2 | ||||
i | 1 | 0 | 1 | |||
v | 2 | 1 | 0 | |||
a | 3 | 2 | 1 | |||
n | 4 | 3 | 2 | |||
2 | 5 | 4 | 3 |
依次类推直到矩阵全部生成
i | v | a | n | 1 | ||
0 | 1 | 2 | 3 | 4 | 5 | |
i | 1 | 0 | 1 | 2 | 3 | 4 |
v | 2 | 1 | 0 | 1 | 2 | 3 |
a | 3 | 2 | 1 | 0 | 1 | 2 |
n | 4 | 3 | 2 | 1 | 0 | 1 |
2 | 5 | 4 | 3 | 2 | 1 | 1 |
4、相似度-->
1-matrix[m-1,n-1]/max(m-1,n-1)
5、代码实现-->
python--->
def minEditDist(sm, sn): m, n=(len(sm)+1, len(sn)+1) minEdit = [[0]*n for i in range(m)] minEdit[0][0] = 0 for i in range(1,m): minEdit[i][0] = minEdit[i-1][0] + 1 for i in range(1,n): minEdit[0][i] = minEdit[0][i-1] + 1 for i in range(m): print(minEdit[i]) print('****calculate-minDist****') for i in range(1,m): for j in range(1,n): if sm[i-1] == sn[j-1]: tem = 0 else: tem = 1 minEdit[i][j] = min(minEdit[i-1][j]+1, minEdit[i][j-1]+1,minEdit[i-1][j-1]+tem) for i in range(m): print(minEdit[i]) return 1-minEdit[m-1][n-1]/max(m-1,n-1) aa = ["气垫男士", "气垫男士bb霜"] print('相关度为:',minEditDist(aa[0],aa[1]))
c#实现-->
public class minEditDistance { public float getEditDistance(string sm, string sn) { int m = sm.Length; int n = sn.Length; int temp = 0, j = 0, i = 0; if (n == 0) return m; if (m == 0) return n; int[,] minEdit = new int[m + 1, n + 1]; for(i=0;i<= n;i++) { minEdit[0, i] = i; } for(i=0;i<= m;i++) { minEdit[i, 0] = i; } for(i=1;i<= m;i++) { for(j=1;j<= n;j++) { if (sm[i - 1] == sn[j - 1]) { temp = 0; } else { temp = 1; } minEdit[i, j] = Math.Min(minEdit[i - 1, j] + 1, Math.Min(minEdit[i, j - 1] + 1, minEdit[i - 1, j - 1] + temp)); } } for(i=0;i<= m;i++) { for(j=0;j<= n;j++) { Console.Write(minEdit[i, j] + " "); } Console.WriteLine(""); } return 1-minEdit[m,n]*1.0f/Math.Max(m, n); } }