一、编辑距离存在多种定义:
1、
Jaro–Winkler distance,仅允许交换操作;
2、Hamming distance,仅允许替换操作,并要求两个字符串长度相同;
3、Longest common subsequence distance,仅允许插入和删除操作;
4、Levenshtein distance,又称作编辑距离,允许插入、删除和替换操作,但不允许交换操作,满足三角不等式,可以作为度量标准;
5、Damerau-Levenshtein distance,允许插入、删除、替换和交换相邻字符四种操作,不限定子串被操作的次数;
6、Optimal String Alignment,又称restricted edit distance(受限编辑距离)为
Damerau-Levenshtein distance的受限形式,记限定子串仅能被操作一次,OSA(CA,ABC)为3,记CA->A->AB->ABC,而
Damerau-Levenshtein distance为2,距离为CA->AC->ABC,
Optimal String Alignment不满足三角不等式(OSA(CA,AC)+OSA(AC,ABC)
自然处理中经常使用的为
Levenshtein distance和
Optimal String Alignment,依需要进行选择即可。
Levenshtein distance的动态规划算法:
- 如果i == 0 且 j == 0,edit(i, j) = 0
- 如果i == 0 且 j > 0,edit(i, j) = j
- 如果i > 0 且j == 0,edit(i, j) = i
- 如果0 < i ≤ 1 且 0 < j ≤ 1 ,edit(i, j) == min{ edit(i-1, j) + 1, edit(i, j-1) + 1, edit(i-1, j-1) + f(i, j) },这里当字符串1的第i个字符不等于字符串2的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。
Optimal String Alignment的动态规划算法:
- 如果i == 0 且 j == 0,edit(i, j) = 0
- 如果i == 0 且 j > 0,edit(i, j) = j
- 如果i > 0 且j == 0,edit(i, j) = i
- 如果0 < i ≤ 1 且 0 < j ≤ 1 ,edit(i, j) == min{ edit(i-1, j) + 1, edit(i, j-1) + 1, edit(i-1, j-1) + f(i, j) },这里当字符串1的第i个字符不等于字符串2的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。
- 如果i > 1且 j > 1时,这个时候可能出现操作(4),由之前的推导,我们只能交换一次,否则就没有意义。这个时候在比较最小值中可能加入edit(i-2, j-2) +1,什么时候加入呢?假设i-2长度的字符串1子串和j-2长度的字符串2子串已经得出最优解,这个时候如果s1[i-1] == s2[j] 并且s1[i] == s2[j-1],这时就在比较值中加入edit(i-2, j-2) + 1(这个1是交换一次的操作)
二、个人理解:
假设两个字符串A(1..i-1)和B(1..j-1)的编辑距离为a,求在两个字符串中分别加入A[i]和B[j]后的连个字符串的编辑距离。
首先:Edit(A(1..i), B(1..j)) >= Edit(A(1..i-1), B(1..j-1)),这一点是显而易见的;
其次:Edit(A(1..i), B(1..j))最多比Edit(A(1..i-1), B(1..j-1))大一,即Edit(A(1..i), B(1..j)) <= Edit(A(1..i-1)+1;
基于上面两点可以得出这样的结论:
Edit(A(1..i-1), B(1..j-1))+1 >= Edit(A(1..i), B(1..j)) >= Edit(A(1..i-1), B(1..j-1))
在两个字符串中任一个后添加一个字符,得到的编辑距离可能有三种情况:a-1,a和a+1;
下面基于Edit(A(1..i-1), B(1..j-1))推理Edit(A(1..i), B(1..j))
当A[i]=B[j]时,添加这两个字符不会改变字符串的编辑距离;
当A[i]!=B[j]时,可以分为三个情况:
1)、假设添加A[i]使得Edit(A(1..i), B(1..j-1))=a-1;此时加上B[j],则Edit(A(1..i), B(1..j))只能等于a,因为Edit(A(1..i), B(1..j)) >= Edit(A(1..i-1), B(1..j-1));
2)、假设添加B[j]使得Edit(A(1..i-1), B(1..j))=a-1;此时加上A[i],则Edit(A(1..i), B(1..j))也只能等于a,因为Edit(A(1..i), B(1..j)) >= Edit(A(1..i-1), B(1..j-1));
3)、如果上边两种情况均不出现,则在A(1..i-1)和B(1..j-1)的基础上添加A[i]和B[j],则Edit(A(1..i), B(1..j)) 只能是 Edit(A(1..i-1), B(1..j-1)) + 1;
综合考虑,Edit(A(1..i), B(1..j)) = min(Edit(A(1..i), B(1..j-1))+1, Edit(A(1..i-1), B(1..j))+1, Edit(A(1..i-1), B(1..j-1))+1)。
参考文献:
1、动态规划求编辑距离,http://qinxuye.me/article/get-edit-distance-by-dynamic-programming/,
2、Damerau–Levenshtein distance,http://en.wikipedia.org/wiki/Damerau–Levenshtein_distance,
3、Levenshtein distance,http://en.wikipedia.org/wiki/Levenshtein_distance,
4、Edit distance,http://en.wikipedia.org/wiki/Levenshtein_distance,