所以我刚刚开始阅读MED,但完全无法遵循它。 假设我必须将“WATER”转换为“ATERW” 现在我可以替换:
W->A, A->T, T->E, E->R, R->W
因此总成本= 2 + 2 + 2 + 2 + 2 = 10(所有替换)
然而,我知道这不正确,应该是这样的
WATER-
-ATERW
因此总费用= 1 + 1 = 2(删除和插入)
但后来我的问题是程序如何知道它不匹配'W'->'A'
,而是删除'W'
并匹配'ATER'
两个字符串?这种直觉/逻辑如何灌输到程序中?
答案 0 :(得分:3)
首先,您应查看有关Levenshtein距离的维基百科页面:https://en.wikipedia.org/wiki/Levenshtein_distance
就像编辑距离一样,编辑费用除外。
正如您所看到的,要解决此问题,您必须构建一个矩阵(它是一种动态编程方法)。行代表源词,列代表目标词。
首先用基本情况初始化矩阵:
现在你得到了第一行和第一列。
_ A T E R W
_ 0 1 2 3 4 5
W 1 ? ? ? ? ?
A 2 ? ? ? ? ?
T 3 ? ? ? ? ?
E 4 ? ? ? ? ?
R 5 ? ? ? ? ?
这个想法是逐个细胞填充矩阵。填充的第一个将是第二行(2,2)的第二列的单元格。它对应于源词(即WATER)的字母W,以及目标词(ATERW)的字母A.
让我们看看周围的值,让我们为每个值添加一个编辑成本。然后我们会选择最低限度。 对于插入(左侧单元格)或删除(上部单元格),编辑成本始终为1.对于替换(左上角单元格),如果字母不同则编辑成本为1,否则为0。
我们有:
现在选择最小值:1(替换)。单元格2,2现在为值1。
_ A T E R W
_ 0 1 2 3 4 5
W 1 1 ? ? ? ?
A 2 ? ? ? ? ?
T 3 ? ? ? ? ?
E 4 ? ? ? ? ?
R 5 ? ? ? ? ?
现在让我们对2,3号单元做同样的事情。它对应于源词的后W(即WATER),以及目标词(ATERW)的字母T.
我们有:
现在选择最小值:2(INSERTION或SUBSTITUTION)。单元格2,3现在为2。
这意味着将W转换为AT的成本为2。
_ A T E R W
_ 0 1 2 3 4 5
W 1 1 2 ? ? ?
A 2 ? ? ? ? ?
T 3 ? ? ? ? ?
E 4 ? ? ? ? ?
R 5 ? ? ? ? ?
如您所见,我们使用先前的计算(单元格2,2中的值)来填充当前单元格(2,3)。这就是动态编程的想法。
重复直到矩阵填满。它应该是这样的:
_ A T E R W
_ 0 1 2 3 4 5
W 1 1 2 3 4 4
A 2 1 2 3 4 5
T 3 2 1 2 3 4
E 4 3 2 1 2 3
R 5 4 3 2 1 2
看一下最后一个单元格(6,6):值是2.它对应于将'WATER'转换为'ATERW'的成本。
为了恢复执行的编辑操作序列,您可以使用backpointer表。对于给定的单元格,每一行都给出了从中选择最小值的单元格。
2,2 1,1
2,3 2,2
2,4 2,3
2,5 2,4
2,6 1,5
3,2 2,1
...
6,5 5,4
6,6 6,5
现在你可以向后解析表并构建路径,即(6,6) - > (6,5) - > (5,4)......