我的问题是我们希望用户输入如下代码:
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距离之类的东西,但忽略了用户在第二个字符串中添加的缺失字母,但这样会在代码中间出现错误的字母。
在用户输入中搜索代码看起来好一点,但仍然不是很干净。
答案 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然后:
如果您可以通过这种方式完全消耗c1,那么您会发现完全匹配(Levenshtein距离为0)。
否则尝试Levenshtein距离为1的3种可能性:
仅向后移动c1的指针并查看其余部分是否匹配(删除)。
仅向后移动句子的指针,看其余部分是否匹配(插入)。
向后移动两个指针并查看其余指针是否匹配(替换)。
如果其中一个成功,则发现Levenshtein距离为1的匹配,否则距离更远。