【问题标题】:How do spell checkers work? [closed]拼写检查器如何工作? [关闭]
【发布时间】:2010-09-25 16:41:09
【问题描述】:

我需要在 C 中实现一个拼写检查器。基本上,我需要所有标准操作...我需要能够对一段文本进行拼写检查,提出单词建议并动态地将新单词添加到索引中。

我有点想自己写这篇文章,但我真的不知道从哪里开始。

【问题讨论】:

  • 请先完成一些工作,然后再将其交给 Stack Overflow。勾勒出一个设计,找出阻碍你取得进展的关键障碍,告诉我们这将使用的上下文 - 付出一些努力。
  • 如果您正在寻找诸如“阅读本文:链接”之类的答案,请这样说。你可能会得到更好的回应。
  • 所以,保罗,这个问题不是一个好的“stackoverflow”问题吗?究竟如何?你知道,互联网上的一个页面叫做“拼写检查是如何工作的?”对于刚开始学习这些东西是如何工作的人来说,提供深思熟虑的答案将是一件有用的事情。
  • 按照措辞,我认为这不是一个好问题,不。我认为它需要更多的上下文来说明你为什么需要写一个,以及你事先做了什么。它要求 Stackoverflow 为您完成工作。也许只有我。
  • 对于有效确定一个词是否在字典中的核心问题,一种流行的技术是使用Bloom filter

标签: c spell-checking


【解决方案1】:

阅读Tree Traversal。基本概念如下:

  1. 将字典文件读入内存(该文件包含给定语言可能/常见的正确拼写单词的完整列表)。您可以在线下载免费的词典文件,例如Oracle's example dictionary
  2. 将此字典文件解析为搜索树,以使实际文本搜索尽可能高效。我不会描述这种树结构的所有脏细节,但是树将由节点组成,这些节点(最多)有 26 个到子节点的链接(每个字母一个),加上一个标志来指示是否当前节点是否是有效单词的结尾。
  3. 遍历文档中的所有单词,并根据搜索树检查每个单词。如果您到达树中的节点,其中单词中的下一个字母不是当前节点的有效子节点,则该单词不在字典中。此外,如果您到达单词的结尾,并且该节点上未设置“单词的有效结尾”标志,则该单词不在字典中。
  4. 如果在字典中找不到单词,请通知用户。在这个阶段,您还可以建议替代拼写,但这会有点复杂。您将不得不遍历单词中的每个字符,替换替代字符并针对搜索树测试每个字符。寻找推荐词可能有更有效的算法,但我不知道它们是什么。

一个非常简短的例子:

字典:

apex 苹果任命

树:(* 表示有效的词尾) 更新:感谢 Curt Sampson 指出此数据结构称为 Patricia Tree

A -> P -> E -> X*
      \\-> P -> L -> E*
           \\-> O -> I -> N -> T* -> E -> D*

文档:

apple appint 猿

结果:

  • “apple”将在树中找到,因此它被认为是正确的。
  • “appint”将被标记为不正确。遍历树,你会跟随A -> P -> P,但是第二个P 没有I 子节点,所以搜索失败。
  • “ape”也将失败,因为A -> P -> E 中的E 节点没有设置“有效词尾”标志。

编辑:有关拼写建议的更多详细信息,请查看Levenshtein Distance,它衡量了将一个字符串转换为另一个字符串所需进行的最少更改次数。最好的建议是与拼写错误的单词之间的 Levenshtein 距离最小的字典单词。

【讨论】:

  • 我添加了指向关于 Levenshtein Distance 的 Wikipedia 文章的链接。这是我能找到的最好的测量算法,可以根据单词与目标单词的距离(在这种情况下是拼写错误的单词)对单词进行排名
  • 2 中描述了一个三叉树。它有一个相当大的空间权衡。
  • @HeretoLearn:我认为这不正确。三叉树每个节点最多有 3 个子节点,但我描述的结构每个节点最多有 26 个子节点。
  • 使用哈希表有用吗?您可以将输入字符串转换为整数,然后在单词数组中查找它?这与一棵树相比如何?
【解决方案2】:

鉴于您不知道从哪里开始,我建议您使用现有的解决方案。例如,参见aspell (GLPL 许可)。如果您真的必须自己实现,请告诉我们原因。

【讨论】:

  • 我很好奇。我可能会选择使用现有的包,但我想先了解这个问题。在谷歌搜索了一下之后,我正在考虑对字典使用 levenstein 距离算法,但我不确定这是否足够快(速度和代码大小很重要)。
  • 另一个开源拼写检查器是hunspell,它被OOo和Mozilla使用。
【解决方案3】:

应该看看前缀和后缀。

突然=突然+突然。

通过删除 ly's,您可以避免只存储词根。

同样preallocate = pre + allocate。

并且充满爱意 = 爱 + ing + ly 变得有点复杂,因为 ing 的英文规则被调用。

还有可能使用某种散列函数来映射一个词根 进入特定位是一个大位图,作为确定根词是否拼写正确的恒定时间方法。

您可以通过尝试为拼写错误的单词提供可能正确拼写的替代列表来变得更加复杂。您可以研究 soundex 算法以获得一些想法。

我会建议用一小组单词进行原型设计。做大量测试,然后扩大规模。 这是一个很好的教育问题。

【讨论】:

  • 我不能同意这一点。众所周知,从算法上提取英语单词是不准确的。在黑暗时代节省空间和时间可能是值得的,但现在不值得了。
  • “英语不会从其他语言中借用,它会跟随他们进入黑暗的小巷,将他们撞倒,并从他们的口袋里寻找松散的语法。”
【解决方案4】:

将单词分成词根和后缀被称为“Porter Stemming Algorithm”,这是一种将英文词典放入极小的记忆的好方法。
它对 seach 也很有用,因此“拼写检查”也会找到“拼写检查”和“拼写检查”

【讨论】:

    【解决方案5】:

    我在课堂上做过这个

    您应该考虑专门用于处理此问题的 python Natural Language Toolkit NLTK

    它还允许创建文本解释器,例如聊天机器人

    【讨论】:

      【解决方案6】:

      Open Office 拼写检查程序 Hunspell 是一个很好的起点。这是主页: Hunspell at Sourceforge

      【讨论】:

        【解决方案7】:

        E James 给出了一个很好的答案来判断一个词是否有效。这可能取决于拼写检查器如何确定可能的拼写错误。

        一种这样的方法,我将使用的方法是Levenshteinn String Similarity,它查看必须在一个单词中添加、删除或交换多少个字母才能生成另一个单词。

        如果你说拼写:Country as Contry。 levenshtein 字符串相似度为 1,因为您只需添加 1 个字母即可将国家/地区转换为国家/地区。

        然后,您可以遍历所有可能的正确拼写单词(只有 171,000 个英文单词,其中 3000 个占文本的 95%)。确定那些具有最低 levenshtein 字符串相似度值的词,然后返回与拼写错误的词最相似的前 X 个词。

        有一个很棒的 Python 包,名为 Fuzzy Wuzzy,它有效地实现了这一点,并根据这个公式在两个单词或句子之间生成 % 相似度。

        【讨论】:

          猜你喜欢
          • 2013-08-19
          • 2010-10-26
          • 1970-01-01
          • 2013-03-27
          • 2012-04-18
          • 2011-08-17
          • 1970-01-01
          • 2012-02-02
          • 2011-04-18
          相关资源
          最近更新 更多