概述
在日常应用中,文本比较是一个比较常见的问题。文本比较算法也是一个老生常谈的话题。
文本比较的核心就是比较两个给定的文本(可以是字节流等)之间的差异。目前,主流的比较文本之间的差异主要有两大类。一类是基于编辑距离(Edit Distance)的,例如LD算法。一类是基于最长公共子串的(Longest Common Subsequence),例如Needleman/Wunsch算法等。
LD算法(Levenshtein Distance)又成为编辑距离算法(Edit Distance)。他是以字符串A通过插入字符、删除字符、替换字符变成另一个字符串B,那么操作的过程的次数表示两个字符串的差异。
对于1≤i≤N,1≤j≤M,有公式一
若ai=bj,则LD(i,j)=LD(i-1,j-1)
若ai≠bj,则LD(i,j)=Min(LD(i-1,j-1),LD(i-1,j),LD(i,j-1))+1
举例说明:A=GGATCGA,B=GAATTCAGTTA,计算LD(A,B)
第一步:初始化LD矩阵
| | G | A | A | T | T | C | A | G | T | T | A |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
G | 1 | | | | | | | | | | | |
G | 2 | | | | | | | | | | | |
A | 3 | | | | | | | | | | | |
T | 4 | | | | | | | | | | | |
C | 5 | | | | | | | | | | | |
G | 6 | | | | | | | | | | | |
A | 7 | | | | | | | | | | | |
第二步:利用上述的公式一,计算第一行
| | G | A | A | T | T | C | A | G | T | T | A |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
G | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
G | 2 | | | | | | | | | | | |
A | 3 | | | | | | | | | | | |
T | 4 | | | | | | | | | | | |
C | 5 | | | | | | | | | | | |
G | 6 | | | | | | | | | | | |
A | 7 | | | | | | | | | | | |
第三步,利用上述的公示一,计算其余各行
| | G | A | A | T | T | C | A | G | T | T | A |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
G | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
G | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 7 | 8 | 9 |
A | 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 8 |
T | 4 | 3 | 2 | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
C | 5 | 4 | 3 | 3 | 2 | 2 | 2 | 3 | 4 | 5 | 6 | 7 |
G | 6 | 5 | 4 | 4 | 3 | 3 | 3 | 3 | 3 | 4 | 5 | 6 |
A | 7 | 6 | 5 | 4 | 4 | 4 | 4 | 3 | 4 | 4 | 5 | 5 |
则LD(A,B)=LD(7,11)=5
下面是LD算法的代码,用的是VB2005。代码格式修正于2012年1月6日。
Private
Private
Public
mA = A.ToCharArray
mB = B.ToCharArray
Dim
Dim
For
L(i, 0) = i
Next
For
L(0, j) = j
Next
For
For
If
L(i, j) = L(i - 1, j - 1)
Else
L(i, j) = Min(L(i - 1, j - 1), L(i - 1, j), L(i, j - 1)) + 1
End
Next
Next
Return
End
Public
Dim
If
If
Return
End
End
这个LD算法时间复杂度为O(MN),空间复杂度为O(MN),如果进行优化的话,空间复杂度可以为O(M),优化的代码这里不再详述了。参看“计算字符串的相似度(VB2005)”
我们往往不仅仅是计算出字符串A和字符串B的编辑距离,还要能得出他们的匹配结果。
以上面为例A=GGATCGA,B=GAATTCAGTTA,LD(A,B)=5
他们的匹配为:
A:GGA_TC_G__A
B:GAATTCAGTTA
如上面所示,蓝色表示完全匹配,黑色表示编辑操作,_表示插入字符或者是删除字符操作。如上面所示,黑色字符有5个,表示编辑距离为5。
利用上面的LD矩阵,通过回溯,能找到匹配字串
第一步:定位在矩阵的右下角
| | G | A | A | T | T | C | A | G | T | T | A |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
G | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
G | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 7 | 8 | 9 |
A | 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 8 |
T | 4 | 3 | 2 | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
C | 5 | 4 | 3 | 3 | 2 | 2 | 2 | 3 | 4 | 5 | 6 | 7 |
G | 6 | 5 | 4 | 4 | 3 | 3 | 3 | 3 | 3 | 4 | 5 | 6 |
A | 7 | 6 | 5 | 4 | 4 | 4 | 4 | 3 | 4 | 4 | 5 | 5 |
第二步:回溯单元格,至矩阵的左上角
若ai=bj,则回溯到左上角单元格
| | G | A | A | T | T | C | A | G | T | T | A |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
G | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
G | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 7 | 8 | 9 |
A | 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 8 |
T | 4 | 3 | 2 | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
C | 5 | 4 | 3 | 3 | 2 | 2 | 2 | 3 | 4 | 5 | 6 | 7 |
G | 6 | 5 | 4 | 4 | 3 | 3 | 3 | 3 | 3 | 4 | 5 | 6 |
A | 7 | 6 | 5 | 4 | 4 | 4 | 4 | 3 | 4 | 4 | 5 | 5 |
若ai≠bj,回溯到左上角、上边、左边中值最小的单元格,若有相同最小值的单元格,优先级按照左上角、上边、左边的顺序
| | G | A | A | T | T | C | A | G | T | T | A |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
G | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
G | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 7 | 8 | 9 |
A | 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 8 |
T | 4 | 3 | 2 | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
C | 5 | 4 | 3 | 3 | 2 | 2 | 2 | 3 | 4 | 5 | 6 | 7 |
G | 6 | 5 | 4 | 4 | 3 | 3 | 3 | 3 | 3 | 4 | 5 | 6 |
A | 7 | 6 | 5 | 4 | 4 | 4 | 4 | 3 | 4 | 4 | 5 | 5 |
若当前单元格是在矩阵的第一行,则回溯至左边的单元格
若当前单元格是在矩阵的第一列,则回溯至上边的单元格
| | G | A | A | T | T | C | A | G | T | T | A |
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
G | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
G | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 7 | 8 | 9 |
A | 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 8 |
T | 4 | 3 | 2 | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
C | 5 | 4 | 3 | 3 | 2 | 2 | 2 | 3 | 4 | 5 | 6 | 7 |
G | 6 | 5 | 4 | 4 | 3 | 3 | 3 | 3 | 3 | 4 | 5 | 6 |
A | 7 | 6 | 5 | 4 | 4 | 4 | 4 | 3 | 4 | 4 | 5 | 5 |
依照上面的回溯法则,回溯到矩阵的左上角
第三步:根据回溯路径,写出匹配字串
若回溯到左上角单元格,将ai添加到匹配字串A,将bj添加到匹配字串B
若回溯到上边单元格,将ai添加到匹配字串A,将_添加到匹配字串B
若回溯到左边单元格,将_添加到匹配字串A,将bj添加到匹配字串B
搜索晚整个匹配路径,匹配字串也就完成了
从上面可以看出,LD算法在不需要计算出匹配字串的话,时间复杂度为O(MN),空间复杂度经优化后为O(M)
最后
以上就是个性冬瓜为你收集整理的文本对比。文本编辑距离算法的全部内容,希望文章能够帮你解决文本对比。文本编辑距离算法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复