检查一个字符串是否包含Levenshtein距离为1的子字符串与其他字符串

时间:2017-12-05 13:07:26

标签: algorithm string-matching levenshtein-distance

我的问题是我们希望用户输入如下代码: 639195-EM-66-XA-53-WX输入中的某个位置,结果可能如下所示:The code is 639195-EM-66-XA-53-WX, let me in。我们仍然希望匹配字符串,如果它们在代码中产生一个小错误(Levenshtein距离为1)。例如The code is 739195-EM-66-XA-53-WX, let me in。 (在代码的第一个字母中将6更改为7

即使用户跳过破折号,算法也应该匹配,并且它应该忽略小写/大写字母。这些要求很容易实现,因为我可以删除所有破折号并执行to_uppercase。

是否有类似的算法?

生成与原始代码距离为1的所有字符串在计算上非常昂贵。

我还在考虑使用Levenshtein距离之类的东西,但忽略了用户在第二个字符串中添加的缺失字母,但这样会在代码中间出现错误的字母。

在用户输入中搜索代码看起来好一点,但仍然不是很干净。

1 个答案:

答案 0 :(得分:2)

我有一个解决方案的想法,也许这对你来说已经足够了:

正如你所说,首先删除短划线并使所有上部(或下部)大小写:

句子:THE CODE IS 639195EM66XA53WX, LET ME IN

代码:639195EM66XA53WX

将代码拆分在中间(c1和c2),因为Levenshtein距离为1意味着只能有一个错误(插入,删除或替换单个字符),因此c1或c2中的一个必须匹配代码出现在句子中,只有1个或更少的错误。在中间拆分,因为代码的两个子串越长,你应该得到的匹配越少:

c1:639195EM

c2:66XA53WX

现在尝试在你的句子中找到c1和c2,如果你找到一个匹配,你要么必须前进(c1匹配)或后退(c2匹配)在句子中检查缺失部分的Levenshtein距离是否为1或更少。

所以在你的例子中你会找到c2然后:

  1. 设置指向c1的最后一个字符和匹配前的字符的指针。
  2. 当字符相同时,将两个指针减少1(在两个字符串中向后移动)。
  3. 如果您可以通过这种方式完全消耗c1,那么您会发现完全匹配(Levenshtein距离为0)。

  4. 否则尝试Levenshtein距离为1的3种可能性:

    1. 仅向后移动c1的指针并查看其余部分是否匹配(删除)。

    2. 仅向后移动句子的指针,看其余部分是否匹配(插入)。

    3. 向后移动两个指针并查看其余指针是否匹配(替换)。

  5. 如果其中一个成功,则发现Levenshtein距离为1的匹配,否则距离更远。