如何匹配两个字符串,但同时允许X个字符在匹配中不正确。错误数量应该是一个可控制的变量。
虽然字符串中X个字符的数量不匹配,但是应该限制序列中有多少个字符。给定两个字符串,我可能允许5个字符不同,但不能连续超过2个。
我正在寻找一种推荐的算法来比较这两个字符串,或者也许已经有一个已知的解决方案。
如何匹配两个字符串,但同时允许X个字符在匹配中不正确。错误数量应该是一个可控制的变量。
虽然字符串中X个字符的数量不匹配,但是应该限制序列中有多少个字符。给定两个字符串,我可能允许5个字符不同,但不能连续超过2个。
我正在寻找一种推荐的算法来比较这两个字符串,或者也许已经有一个已知的解决方案。
Answers:
近似的字符串搜索起点是Levenshtein距离的起点。该算法计算将单个单词更改为另一个单词的单字符编辑(插入,删除和替换)的次数。
这样的一个例子是kitten
- > sitting
它具有为3的编辑距离
此算法有多种变化,尤其是Damerau–Levenshtein距离允许两个相邻字符(“ hte”到“ the”的DL距离为1,Levenshtein距离为2)的换位,因此通常更适合拼写检查。对于间隙很重要的应用(DNA字符串),还存在其他变体。
Levenshtein距离是众所周知的,并不是很难找到的(我曾经有理由寻找它在oracle中作为函数的实现-比拉下所有数据然后运行查询代码端要快得多)。Rosettacode具有Levenshtein距离的多种含义(54)(请注意,某些语言在某处将其作为字符串库的一部分-如果您使用Java,请查看apache commons lang)。 Wikibooks有31种实现,并且粗略地浏览了两者,却没有显示相同语言的相同代码。
它的工作方式是建立一个与两个字符串之间的关系相对应的矩阵:
.kitten
.0123456
s1123456
i2212345
t3321234
t4432123
i5543223
n6654332
g7765443
该.
行和列的代表,您可以通过“只是”插入从空字符串每个字母到达目标字符串。这不是理想的情况,但是可以为算法注入种子。
如果该值与该点相同('i'=='i'),则该值与对角线到左上方的值相同。如果两个点不相同('!'!='k'),则该值为以下项中的最小值:
编辑距离返回值是矩阵右下角的值。
如果从右下角到左上角以最小的顺序进行操作,则可以看到所做的修改:
.kitten
.0. .
s.1 .
i 1 .
t 1 .
t 1.
i.....2
n 2
g......3
请注意,这是占用大量内存的方法。可以通过不构建完整的矩阵来减少内存范围-算法所关心的只是数据的一个子集,并且可以通过仅存储前一行(以及在当前行上计算出的内容)N*M
来2*max(N,M)
逐个空间地减少它。行)。 Code Project展示了如何做到这一点(需要下载C#代码)。