【问题标题】:Generate deletion, insertion, substitution, transpotions for a string为字符串生成删除、插入、替换、转位
【发布时间】:2012-12-03 01:13:26
【问题描述】:

我正在实施拼写检查算法。我已经构建了一个 Trie 来存储我的单词以便快速搜索。

当传递给定的输入字符串时,我想做的是为该字符串生成潜在的删除、插入、替换和转置,编辑距离为 1。使用这个超集,我可以尝试在我的 @ 中找到这个词987654322@ 并向用户提供“您的意思是?”输入结果。

我在网上查看过,大多数解决方案都提到了计算莱文斯坦距离。仅当您已经知道这两个字符串并且想要找到两者之间的编辑距离时,这才有效。

建议?

【问题讨论】:

  • 1) 你可以通过 trie-tree 遍历并计算 levenstein 距离(使用一些切割启发式)
  • 嗯,不错的建议……你能补充更多吗?
  • 因此,levenstein 算法可以描述为递归函数 D(i,j),它接受 (m,n) 其中 m - 第一个字符串的长度,n - 第二个字符串的长度。让修复第一个字符串并将其视为输入字符串。因此,计算 d("input","ab") 调用 d("input","a")。计算 d("input","ac") 调用 d("input","a")。看?您计算当前节点的 ldistance,遍历子节点并根据当前节点的 precalf 为他们计算 ldistance。
  • 现在,关于剪切启发式。你不需要 ldistance >= 7 的词。更多:你只需要 N 个词来为用户推荐它们。对树使用某种 djkstra 算法
  • 是的,您建议生成单词的所有修改。所有修改的生成都很慢。所以最好计算 trie 中所有单词的 Levenstain 距离,因为所有单词都有一些共同的前缀,并且它们的 LD 可以被缓存

标签: java algorithm


【解决方案1】:

我会使用 2 pass 算法:

通过 1

查看并计算所有以与单词相同的字母开头的单词的距离以进行拼写检查。这会很快。当字符数大于拼写单词长度 + 2(那么这显然是另一个单词)时,您可以停止深度搜索
显示pass1的结果,例如用红色下划线标记单词

通过 2

查找所有单词并在长度 + 3 或 4 时停止 更新通过 1 中找到的结果

【讨论】:

  • 你能提供一些代码吗?如果我得到字符串测试,我想生成 tst tes tast tbst 或 etst 等,然后针对我的 trie 测试该输入。
  • 我不会生成 tst tes tast 等。您应该迭代 trie 并计算从 trie 中正确单词到要进行拼写检查的单词的 leving 距离。仅当距离为 1 或 2 时才将单词添加到结果列表中。最后按距离对结果进行排序,并显示前 5 个结果。
  • 当您说“迭代”特里树时,假设输入是“trst”(用户打错字),我是否会尽可能多地生成所有可能的结果,直到最准确的字符我到了?例如,给定输入“trst”,我将开始遍历特里树。我看到't'匹配然后我继续前进,看到'r'不见了。我是否应该遍历特里树中的其余节点,然后比较列文斯坦距离?
  • @dnkoutso 是的。您必须遍历所有方向,即使它们不包含字符(或包含新/另一个)。你的切割启发式 - levDistance > length(word) + magicConstant
  • 以“t”开头并迭代子树,这样您就可以计算所有以 t 开头的单词的 levin 分布。 (当这可行时,您可以引入一个停止条件,在此情况下,深入迭代 trie 是没有意义的)。在 trie 的某处,您会发现 dist = 1 的单词“test”,将对象 (test, 1) 添加到您的候选结果中。
猜你喜欢
  • 2017-03-24
  • 2019-06-21
  • 2019-06-21
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多