【问题标题】:How to find the combination of words that includes all the letters in the input with Python如何使用Python查找包含输入中所有字母的单词组合
【发布时间】:2013-06-16 23:44:15
【问题描述】:

如果可行,我想找到最有效的方法来遍历在 Python 中输入的字母组合,并返回一组单词,其组合包括所有字母。

例子:

假设用户输入了 A B C D E。目标是找到包含所有字母的最少单词数。在这种情况下,按优先顺序排列的最佳解决方案将是:

  1. 一个包含全部 5 个字母的单词
  2. 包含全部 5 个字母的两个单词。 (可以是 4 个字母的单词 + 1 个字母的单词或 3 个字母的单词 + 2 个字母的单词。没有区别)

.... 等等。

如果不匹配,则返回 1. 用 n-1 个字母等。

我有一个功能可以检查“字母组合”(即单词)是否在字典中。

def is_in_lib(word):
    if word in lib:
        return word
    return False

理想的答案不应包括找到这些字母的组合并搜索所有这些字母。搜索我的字典非常昂贵,所以我需要一些可以优化我们搜索字典的时间的东西

重要编辑:顺序很重要,需要连续性。这意味着如果用户输入“H”、“T”、“A”,则无法构建“HAT”。

真实例子:如果输入是:T - H - G - R - A - C - E - K - B - Y - E " 输出应该是 "Grace" 和 "Bye"

【问题讨论】:

  • 你如何处理多重性?例如:用户给出了两个 'A' 和 4 个不同的字母?
  • 我认为您的方法不可行。组合的数量增长太快,即使是少量字母,检查每个可能的组合也需要大量时间。如果您提供更多上下文,可能有人可以针对您想要做的事情提出更智能的解决方案。
  • 我刚刚编辑了 @fodma1 。由于顺序很重要,因此多重性将不是问题。 (您需要全部使用)
  • @bakuriu 你说得对,这就是我不想走这条路的原因。示例:如果输入是:T - H - G - R - A - C - E - K - B - Y - E "输出应该是 "Grace" 和 "Bye"
  • @PaulMiles 当匹配所有 N 个字母的搜索失败并且我们开始搜索 N-1 个字母的匹配时,应该遵循什么原则指导算法。算法是否可以随意丢弃 N 个字母中的任何一个,还是应该丢弃特定的字母(例如,第一个或最后一个)?换句话说,当从 N 搜索到 N-1 搜索,再到 N-2 等时,算法是否也必须尊重用户输入的连续性。顺便说一句,您应该在强调连续性的问题中添加另一个编辑需求和订购——两者都很重要。

标签: python regex algorithm optimization modeling


【解决方案1】:

您可以从输入字母创建一个字符串/列表,并在词库中的每个单词上迭代它们:

    inputstring='abcde'
    for i in lib:
            is_okay=True
            for j in inputstring:
                    if i.find(j)=-1:
                            is_okay=False
            if is_okay:
                    return i

我认为其他情况(两个单词,3-2个字母)可以递归实现,但效率不高。

【讨论】:

    【解决方案2】:

    我认为这里的关键思想是使用某种索引来提供从规范的字符序列到实际单词的映射。类似的东西:

    # List of known words
    >>> words = ('bonjour', 'jour', 'bon', 'poire', 'proie')
    
    
    # Build the index
    >>> index = collections.defaultdict(list)
    >>> for w in words:
    ...     index[''.join(sorted(w.lower()))].append(w)
    ... 
    

    这将产生一种有效的方法来查找对应于字符序列的所有字谜:

    >>> index
    defaultdict(<class 'list'>, {'joru': ['jour'], 'eiopr': ['poire', 'proie'], 'bjnooru': ['bonjour'], 'bno': ['bon']})
    

    你可以这样查询索引:

    >>> user_str = 'OIREP'
    >>> index.get(''.join(sorted(user_str.lower())), "")
    ['poire', 'proie']
    

    当然,这只会找到“准确”的字谜——即包含所有用户提供的字母。要查找与用户提供的字符串的子集匹配的所有字符串,您必须一次删除一个字母并再次检查每个组合。我觉得 递归 将有助于解决这个问题;)

    编辑: (我应该把它放在剧透部分吗?)

    这是一个可能的解决方案:

    import collections
    
    words = ('bonjour', 'jour', 'bon', 'or', 'pire', 'poire', 'proie')
    
    index = collections.defaultdict(list)
    for w in words:
        index[''.join(sorted(w.lower()))].append(w)
    
    # Recursively search all the words containing a sequence of letters
    def search(letters, result = set()):
        # Assume "letters" ordered
        if not letters:
            return
    
        solutions = index.get(letters)
        if solutions:
            for s in solutions:
                result.add(s)
    
        for i in range(0,len(letters)):
            search(letters[:i]+letters[i+1:], result)
    
        return result
    
    
    # Use case:
    user_str = "OIREP"
    
    s = search(''.join(sorted(user_str.lower())))
    print(s)
    

    制作:

    set(['poire', 'or', 'proie', 'pire'])
    

    这不是那么糟糕,但可以改进,因为相同的字符子集被检查了多次。尤其如此,用户提供的搜索字符串包含多个相同的字母。

    【讨论】:

      猜你喜欢
      • 2015-06-28
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多