【问题标题】:Python: Find all anagrams of a sentencePython:查找句子的所有字谜
【发布时间】:2017-04-05 02:48:30
【问题描述】:

我想从一个短语中找到所有可能的字谜,例如,如果我输入“Donald Trump”,我应该得到“Darn mud plot”、“Damp old runt”,可能还有数百个。

我有一本大约 100,000 字的字典,没有问题。

但我能想到的唯一方法是遍历字典并将所有可以从输入构建的单词添加到列表中。然后遍历列表,如果单词长度小于输入的长度,则再次遍历字典,添加所有可能的单词,这些单词可以由剩余的字母组成,使其长度等于或小于输入的长度。并继续循环,直到我得到所有长度等于输入长度的有效单词的组合。

但这是 O(n!) 复杂度,并且几乎需要永远运行。我试过了。

有没有办法解决这个问题,从而降低复杂性?我可能在网上找到了一些关于 perl 的东西,但我绝对看不懂 perl 代码,尤其是 perl golf。

【问题讨论】:

标签: python string algorithm big-o anagram


【解决方案1】:

我喜欢您将单词列表过滤为仅可能由输入字母组成的单词的想法,并且我喜欢尝试将它们串在一起的想法,但我认为您可以进行一些主要的优化落实到位,可能会加快速度。

对于初学者,与其选择一个单词然后重新扫描整个字典以查找剩余的内容,我会考虑在开始时只进行一次过滤,以查找所有可以用您拥有的字母组成的单词。您的字典可能会非常庞大​​(我怀疑超过 150,000),因此在每个决策点之后重新扫描它是完全不可行的。一旦你有了可以在字谜中合法使用的单词集,接下来你就会遇到一个问题,即找出可以使用它们的哪些组合来形成句子的完整字谜。

我会首先查找与目标字谜的无序单词列表,而不是所有可能的有序单词列表,因为要查找的单词要少得多。一旦你有了无序列表,你就可以很快地从中生成排列。

为此,我会使用回溯递归,在该递归中,您在每个点都维护剩余字母计数的直方图。您可以使用它来过滤掉无法再添加的单词,这基本上可以节省您每次都必须检查整个字典的成本。我想这种递归会死路一条,而且您可能会毫不费力地找到所有答案。

在此过程中,您可能会考虑其他一些启发式方法。例如,您可能希望首先从较大的单词开始提取尽可能多的字母并保持较低的分支因子。为此,您可以将单词列表从最长到最短排序,然后按该顺序尝试单词。您也可以尝试首先使用最受限制的字母来减少分支因子。这些启发式方法在实践中可能会非常有效。

总体而言,在最坏的情况下,您仍在查看指数工作,但对于较短的字符串来说应该不会太糟糕。

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 2016-03-17
    • 2016-03-18
    • 2011-02-03
    • 2013-01-11
    • 2019-06-25
    • 2011-08-30
    • 2017-12-04
    • 2014-04-13
    相关资源
    最近更新 更多