Python 递归函数,用于确定len n的单词组合是否存在

Python 递归函数,用于确定len n的单词组合是否存在,python,recursion,Python,Recursion,我上了一堂递归课和一些作业。这是一个我根本解决不了的问题 我们有一个如下格式的列表['word','blabla','thing']和一个数字L作为输入 我们的想法是,如果字符/单词组合的数量等于L,那么尝试找出是否有方法组合一些单词(或者只取一个)。 注意:如果我们有一个组合,那么我们必须在字符总数中计算逗号(分隔符) 例如:print(递归函数(['word','blabla','thing'],12))应该返回True 实际上blabla的长度是6,东西的长度是5,我们有一个逗号,所以总共

我上了一堂递归课和一些作业。这是一个我根本解决不了的问题

我们有一个如下格式的列表['word','blabla','thing']和一个数字L作为输入

我们的想法是,如果字符/单词组合的数量等于L,那么尝试找出是否有方法组合一些单词(或者只取一个)。 注意:如果我们有一个组合,那么我们必须在字符总数中计算逗号(分隔符)

例如:
print(递归函数(['word','blabla','thing'],12))
应该返回
True

实际上blabla的长度是6,东西的长度是5,我们有一个逗号,所以总共是12

我有以下代码:

def recursive_func(words, L):
  if len(words) == 1 or len(words[-1]) == L:
    return len(words[-1]) == L
  last_word = words[-1]
  without_last_word = words[:-1]
  return ??? or ???
所以我理解代码,因为我以前也做过类似的代码,但我不知道应该在这些“?”上放什么

因为它是关于递归的,我们显然需要放一些类似于
recursive\u func(没有最后一个单词,L)
我的猜测是有必要将L减少
len(单词[-1])
,然后尝试是否有匹配项

但我不知道实际的方法是什么,也不能正确地编写代码

你能给我一个建议吗


非常感谢

诀窍是试着选择一个单词,看看剩下的单词是否存在解决方案。如果没有,那么我们可以删除这个词

def recursive_func(words, L):
    # A direct fit?
    if any(len(w) == L for w in words):
        return True

    # We try the ith word w, and see if a combo solution exists
    # including that word, otherwise we eliminate it.
    for i, w in enumerate(words):
        remaining_candidates = words[i+1:]
        if recursive_func(remaining_candidates, L - len(w) - 1):
            return True
    
    return False

诀窍是试着选择一个单词,然后看看剩下的单词是否存在解决方案。如果没有,那么我们可以删除这个词

def recursive_func(words, L):
    # A direct fit?
    if any(len(w) == L for w in words):
        return True

    # We try the ith word w, and see if a combo solution exists
    # including that word, otherwise we eliminate it.
    for i, w in enumerate(words):
        remaining_candidates = words[i+1:]
        if recursive_func(remaining_candidates, L - len(w) - 1):
            return True
    
    return False

如果您需要任何单词的组合,例如您可以组合
'word'
'thing'
传递示例中的
'blabla'
,您可以编写如下内容:

def recursive_func(words, L, used, cnt):
    if (cnt == L):
        return True
    for i in range(len(words)):
        if (not used[i]):
            used[i] = True
            if (recursive_func(words, L, used, len(words[i]) if cnt == 0 else cnt + len(words[i]) + 1)):
                return True
            used[i] = False
    return False
recursive_func(words, L, [False] * len(words), 0)

其中,
used
是一个数组,它知道当前组合中使用的单词,
cnt
是当前组合的长度。

如果您需要任何单词的组合,比如您可以组合
'word'
'thing'
传递
'blablabla'
,从您的示例中,您可以编写如下内容:

def recursive_func(words, L, used, cnt):
    if (cnt == L):
        return True
    for i in range(len(words)):
        if (not used[i]):
            used[i] = True
            if (recursive_func(words, L, used, len(words[i]) if cnt == 0 else cnt + len(words[i]) + 1)):
                return True
            used[i] = False
    return False
recursive_func(words, L, [False] * len(words), 0)

其中,
used
是一个数组,它知道当前组合中使用的单词,
cnt
是当前组合的长度。

我会这样做:

def recursive_func(words, L):

    if sum(map(len, words)) + len(words) - 1 == L:
        return True
    if len(words) == 1:
        return False

    for w in list(words):
        words.remove(w)
        if recursive_func(words, L):
            return True
        words.append(w)
    return False
首先,检查整个列表是否满足条件,如果不满足,则尝试使用子列表


您可以选择使用
itertools
set

我会这样做:

def recursive_func(words, L):

    if sum(map(len, words)) + len(words) - 1 == L:
        return True
    if len(words) == 1:
        return False

    for w in list(words):
        words.remove(w)
        if recursive_func(words, L):
            return True
        words.append(w)
    return False
首先,检查整个列表是否满足条件,如果不满足,则尝试使用子列表


您可以选择使用
itertools
set

这应该可以解决这个问题。我们在每个递归中构建2棵树(有和没有第一个单词)。请记住,组合中的单词可能不相邻

s =["hi","hallo","du"]

def rec(words:list, L:int):
    if not words:
        return False
    elif len(words[0]) == L:
        return True
        elif len(words[0]) > L:
        return False #early stopping
    return rec(words[1:], L-len(words[0])-1) or rec(words[1:],L) #all combinations with and without this word

print(rec(s, 4))

这应该可以解决问题。我们在每个递归中构建2棵树(有和没有第一个单词)。请记住,组合中的单词可能不相邻

s =["hi","hallo","du"]

def rec(words:list, L:int):
    if not words:
        return False
    elif len(words[0]) == L:
        return True
        elif len(words[0]) > L:
        return False #early stopping
    return rec(words[1:], L-len(words[0])-1) or rec(words[1:],L) #all combinations with and without this word

print(rec(s, 4))

虽然您的直接拟合检查有效,但更简单的基本情况是检查
L==0
@Barmar您是否忘记了逗号。哦,对了,当单个单词匹配时,没有逗号。不需要添加for循环(特别是每个递归中没有2个)。这可以通过递归本身来完成。虽然直接拟合检查有效,但更简单的基本情况是检查
L==0
@Barmar您是否忘记了逗号。哦,对了,当单个单词匹配时没有逗号。不需要添加for循环(尤其是每个递归中没有2个循环)。这可以通过递归本身来完成。不需要更改签名来添加信息,请参阅我的答案。此外,如果你递归地构建两棵树而不是一棵树,那么不需要遍历所有单词。不需要更改签名来添加信息,请参阅我的答案。此外,如果递归地构建两棵树而不是只构建一棵树,则不需要遍历所有单词。