给定一个字符串列表,我可以创建不同的字符串吗?

时间:2018-03-23 10:33:48

标签: python string

所以,我试图创建一个返回True的函数,如果使用给定的字符串列表,它可能会创建一个key word(不同的字符串)。 例如,if list = ["He", "ll", "o"]可以创建单词Hello

到目前为止,我得到了这个:

def canCreateString(pieces, wholeString):
    temp = ""
    result = True
    for each in wholeString:
        result = False
        temp += each
        if temp in pieces:
            temp = ""
            result = True
    return result

print(canCreateString(["dis", "il", "lusio", "ned"], "disillusioned"))

它有效......有点儿。 现在,它创建了这些部分的字符串: 不喜欢 但是,如果我们将列表编辑为:

["dis", "il", "illusio", "ned"]

现在,它还应该从片段创建字符串: dis illusio ned

但相反,它尝试这样:

dis il [can't match more]

所以我的代码有缺陷*。您是否知道我可以重写代码以使其更好用?

3 个答案:

答案 0 :(得分:1)

我发现我参加聚会的时间有点晚了,但这是我的解决方案(很快就会进行检查):

def can_create_string(pieces, str):
    if str == "":
        return True
    l = len(str)
    for i in range(1,l+1):
        temp = str[:i]
        if temp in pieces:
            return can_create_string(pieces, str[i:])
    return False

主要思想是 - 给定一个字符串,我将从头开始对其进行所有可能的切片(例如,对于hello我会检查h,{ {1}},he等)并在hel中查找匹配项。如果我找到了匹配项,那么我需要在字符串的其余部分找到一个匹配项(即递归调用)。基本情况是空字符串,可以在给定任何一组片段的情况下进行组合,因此始终返回true。

如果我找不到任何匹配项,那么我就无法从pieces收集此字符串。

编辑:哦,我看到这是@Aran-Fey回答中完全相同的方法。伟大的思想一样认为:)

答案 1 :(得分:0)

没有重复,天真的单线解决方案是使用itertools.permutations

import itertools
def canCreateString(pieces, whole):
    perms = map(lambda x: ''.join(x), itertools.permutations(pieces)))
    return whole in perms

这段代码正在做的是创建输入数组的每个可能的排列(不同的顺序),然​​后检查所需的输出是否是那些排列的第一部分。

但如果您的棋子数组较大(例如20个元素),这将是低效的。我建议调查Dynamic programming,因为它是一个非常有用的技术,适用于各种编程问题,包括这个问题。

答案 2 :(得分:0)

最直接的解决方案可能是递归解决方案:如果wholeStringpieces中的一段开头,请从wholeString的开头删除它,然后调用canCreateString剩下的文字。

def canCreateString(pieces, wholeString):
    if not wholeString:
        return True

    for piece in pieces:
        if wholeString.startswith(piece):
            remainder = wholeString[len(piece):]
            if canCreateString(pieces, remainder):
                return True

    return False

为了可视化执行流程,canCreateString(["dis", "il", "illusio", "ned"], "disillusioned")将按如下方式进行评估:

  1. canCreateString(["dis", "il", "illusio", "ned"], "disillusioned")被召唤。
  2. “幻灭”以“dis”开头,因此它从字符串中删除。
    1. canCreateString(["dis", "il", "illusio", "ned"], "illusioned")被召唤。
    2. “illusioned”以“il”开头,因此它从字符串中删除。
      1. canCreateString(["dis", "il", "illusio", "ned"], "lusioned")被召唤。
      2. “lusioned”不会以任何部分开头,因此会返回False
    3. “illusioned”以“illusio”开头,因此它从字符串中删除。
      1. canCreateString(["dis", "il", "illusio", "ned"], "ned")被召唤。
      2. “ned”以“ned”开头,因此它从字符串中删除。
        1. canCreateString(["dis", "il", "illusio", "ned"], "")被召唤。
        2. 由于输入字符串为空,因此返回True
  3. 另一种解决方案是使用正则表达式。您创建(?:dis|il|illusio|ned)*形式的正则表达式模式,并检查它是否与字符串匹配:

    import re
    
    def canCreateString(pieces, wholeString):
        pieces = map(re.escape, pieces)
        pattern = r'(?:{})*'.format('|'.join(pieces))
        return bool(re.fullmatch(pattern, wholeString))