【问题标题】:How do I use a Trie for spell checking如何使用 Trie 进行拼写检查
【发布时间】:2020-09-15 21:24:07
【问题描述】:

我有一个从单词词典中构建的 trie。我想将其用于拼写检查(并建议字典中最接近的匹配项,可能是给定数量的编辑 x)。我在想我会在目标单词和字典中的单词之间使用 levenshtein 距离,但是有没有一种聪明的方法来遍历特里树而不实际分别对每个单词运行编辑距离逻辑?我应该如何进行遍历和编辑距离匹配?

例如,如果我有单词 MAN、MANE,我应该能够在 MANE 中重用 MAN 上的编辑距离计算。否则 Trie 不会有任何用途

【问题讨论】:

  • “man/mane”几乎是微不足道的,试试“mane/bane”
  • 我认为这些方法并不适合。您需要对字典中的每个单词应用 edit distance 才能提出建议恕我直言。
  • 是的,但是如何重叠编辑距离计算以避免重新计算相同的距离
  • 好的,这是一个想法:对每个单词运行编辑距离,并对超过确定编辑次数的单词进行修剪(这在大多数情况下无需搜索整个单词)。如何改进它?由于编辑距离是向后计算的,所以 后缀树 可能会表现得更好。当您超过某个编辑阈值时,您可以丢弃整个分支。 (这只是一个疯狂的想法:)

标签: algorithm language-agnostic spell-checking trie


【解决方案1】:

我认为你应该尝试bk-trees;它是一种非常适合拼写检查的数据结构,因为它可以让您有效地计算字典中单词的编辑距离。

这个link 很好地洞察了应用于拼写检查的 BK 树

【讨论】:

    【解决方案2】:

    尝试为每个树节点计算一个数组 A,其中 A[x] 在匹配目标单词的前 x 个字母后,在 trie 中该位置的最小编辑距离。

    如果数组中的每个元素都大于您的目标距离,您可以停止检查任何节点。

    例如,使用包含 MAN 和 MANE 以及输入 BANE 的 trie:

    Node 0 representing '', A=[0,1,2,3,4]
    Node 1 representing 'M', A=[1,1,2,3,4]
    Node 2 representing 'MA', A=[2,1,1,2,3]
    Node 3 representing 'MAN' A=[3,2,2,1,2]
    Node 4 representing 'MANE' A=[4,3,2,2,1]
    

    A[end] 的最小值是 1 与单词“MANE”达到的,因此这是最佳匹配。

    【讨论】:

      【解决方案3】:

      由于以下算法不包含转置,因此有一种智能方法可以获取不是 Levenstein 距离的每个元素。

      假设我们有 Tree 结构,我们可以实现树的递归搜索。您的递归搜索假设我们从表示删除每个字母的成本的成本行开始。当我们递归搜索树时,我们得到的信息是

      • 您位于节点 n,该节点已在您的 Trie 结构中按字母 l 进行索引。
      • 您正在考虑与单词 w 的距离
      • 您当前的路径假设到此之前的成本行,我们希望更新它以形成此节点 n 的新成本行。

      我们希望根据 4 种情况更新您正在考虑的信件中的成本行; l 是单词中的下一个字母(成本行保持不变),需要插入该字母(新成本+1),已删除一个字母(上一步成本+1),该字母替换上一个单词(新费用 +1)。

      在你的树上沿着这条路径前进的成本是这些成本中的最小值。此时,如果您在 Trie 结构中的某个点定义了一个单词,请将其附加到一个列表中,然后假设当前成本在定义的最大成本内,则递归搜索所有子级以查找更多单词。在另一篇文章中可以找到 Python 中的实现:

      https://stackoverflow.com/a/62823597/8249836

      我在 C 中也有这个用于管道。由于该算法即使对于高编辑距离(

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-20
        • 2011-11-12
        • 1970-01-01
        • 2011-07-30
        相关资源
        最近更新 更多