我最近从Wikipedia上的伪代码实现了Damerau-Levenshtein距离算法。我找不到它是如何工作的任何解释和伪采用完全无信息变量的名称,如DA
,DB
,i1
,和j1
我留下抓我的头。
这是我在Python中的实现:https : //gist.github.com/badocelot/5327337
Python的实现帮助我遍历了程序并弄清了正在发生的事情,将变量重命名为更有用的名称。我很熟悉Wagner-Fischer的方法来计算Levenshtein距离,因此有了参考系。
冒着过长的风险,这就是我对Damerau-Levenshtein的理解:
神秘变量:
DA
(last_row
在我的代码中)是一种地图,其中包含每个元素被查看到的最后一行;在我的代码中,这是一个实际的Python字典DB
(last_match_col
)保留最后一列,其中输入的字母b
与a
当前行的输入字母匹配i1
(last_matching_row
)是来自DA
当前字母的行号b
j1
只是DB
/ 值last_match_col
可能被更新之前的副本;在我的代码中,我只是移动了last_match_col
更新并消除了此变量的位置
换位成本:
H[i1][j1] + (i-i1-1) + 1 + (j-j1-1)
正在计算将当前字符换成已知b
的最后一个字符(最后一个匹配项)所花费的费用,将之间的所有字符都视为增加或删除。b
a
成本要素:
H[i1][j1]
将基本成本还原到转置之前的计算点,因为找到转置会使先前的工作无效(i-i1-1)
是当前行与匹配当前字符的最后一行之间的距离,这是需要删除的数量(j-j1-1)
是当前列与具有匹配项的最后一列之间的距离,即相加次数- 多余
+ 1
的只是换位本身的成本
如果此分析不正确,我很想知道我哪里做错了。就像我说的那样,我找不到关于该算法如何在线工作的任何详细说明。
改进版?
已经想通了这一点,虽然,它让我吃惊的是,通过计算成本都增加和调换字母之间的缺失似乎有缺陷的:一个加法和一个删除相当于替代,这,这是不检查。
如果一切正确,那么解决方案应该是微不足道的:转置字母之间的字母成本应为添加和删除中的较高者:将尽可能多的字母转换为替换,并添加所有剩余的添加或删除。
因此成本为:
H[i1][j1] + max((i-i1-1), (j-j1-1)) + 1
这是该版本的代码:https : //gist.github.com/badocelot/5327427
从一些简单的测试来看,这似乎是正确的。例如,“ abcdef”->“ abcfad”的编辑距离为2(转置“ d”和“ f”,将“ e”更改为“ a”),而原始算法给出的距离为3(最后三个)字母是替换,或1个换位+ 1个加+ 1个删除)。
现在,我不能成为第一个想到这一点的人。那么,为什么我没有碰到它呢?我只是搜索时间不够长吗?还是存在一些细微的缺陷使它无法真正起作用?