匹配两个字符串,但允许一定程度的错误


10

如何匹配两个字符串,但同时允许X个字符在匹配中不正确。错误数量应该是一个可控制的变量。

虽然字符串中X个字符的数量不匹配,但是应该限制序列中有多少个字符。给定两个字符串,我可能允许5个字符不同,但不能连续超过2个。

我正在寻找一种推荐的算法来比较这两个字符串,或者也许已经有一个已知的解决方案。


4
Levenshtein距离可能是这样看的,虽然的“连续不超过2”的细节不是算法的一部分。另请参见页面上还有许多其他相关的算法,它们可能正是您想要的。

@MichaelT如果我有类似的东西肯定符合我的需求。谢谢。
Reactgular

@MichaelT我找到了这个> dotnetperls.com/levenshtein您应该把它作为答案,这解决了我的问题。
Reactgular

您可能需要查看Soundex匹配。 en.wikipedia.org/wiki/Soundex
Gilbert Le Blanc

Answers:


12

近似的字符串搜索起点是Levenshtein距离的起点。该算法计算将单个单词更改为另一个单词的单字符编辑(插入,删除和替换)的次数。

这样的一个例子是kitten- > sitting它具有为3的编辑距离

  1. k itten-> s itten(用“ s”代替“ k”)
  2. sitt e n-> sitt i n(用“ i”代替“ e”)
  3. sittin-> sittin g(在末尾添加“ g”)

此算法有多种变化,尤其是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'),则该值为以下项中的最小值:

  • 左上和右上的对角线+ 1(替代)
  • 正上方+1(插入)
  • 直接在左侧+ 1(删除)

编辑距离返回值是矩阵右下角的值。

如果从右下角到左上角以最小的顺序进行操作,则可以看到所做的修改:

 .kitten
.0.   .
s.1   .
i  1  .
t   1 .
t    1.
i.....2
n      2
g......3

请注意,这是占用大量内存的方法。可以通过不构建完整的矩阵来减少内存范围-算法所关心的只是数据的一个子集,并且可以通过仅存储前一行(以及在当前行上计算出的内容)N*M2*max(N,M)逐个空间地减少它。行)。 Code Project展示了如何做到这一点(需要下载C#代码)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.