Мне нужно переписать этот ужасный кусок кода, используя рекурсию в Python. Глубина вложения должна зависеть от аргумента функции rec, но даже я бы хотел, чтобы это была длина переменной «a», которая является строкой. Буду благодарен за любые ответы и подсказки, как решить эту проблему.

def rec():
    count=0
    for i in range(len(letters)):
        for j in range(i+1, len(letters)):
            if letters[i]+letters[j] in a:
                for k in range(j+1, len(letters)):
                    if letters[i]+letters[j]+letters[k] in a:
                        if letters[i]+letters[j]+letters[k]==a:
                            count+=1
                        else:
                            for l in range(k+1, len(letters)):
                                if letters[i]+letters[j]+letters[k]+letters[l]==a:
                                    count+=1

    return count
-1
morteify 4 Мар 2018 в 23:43

3 ответа

Лучший ответ

Кстати, некоторые виды комбинаторной логики легче выразить с помощью itertools чем с рекурсией. Например, когда этот шаблон происходит:

letters = 'ABCDEF'
for i in range(len(letters)):
    a = letters[i]
    for j in range(i+1, len(letters)):
        b = letters[j]
        for k in range(j+1, len(letters)):
            c = letters[k]
            print(a, b, c)

Это можно заменить на это:

from itertools import combinations

letters = 'ABCDEF'
for a, b, c in combinations(letters, 3):
    print(a, b, c)

В вашем вопросе есть нечто большее, чем это, но я хотел бы отметить, что комбинаторные функции являются хорошей отправной точкой для логики, изложенной в этом вопросе.

5
Raymond Hettinger 4 Мар 2018 в 21:06

Этот ужасный код можно переписать, как показано ниже, в итеративном режиме, но это снизит эффективность. То же относится и к рекурсивной функции.

def rec():
    count=0
    for i in range(len(letters)):
        for j in range(i+1, len(letters)):
            for k in range(j+1, len(letters)):
                if letters[i]+letters[j]+letters[k]==a:
                     count+=1
                     continue
                for l in range(k+1, len(letters)):
                    if letters[i]+letters[j]+letters[k]+letters[l]==a:
                         count+=1

    return count
0
sonus21 4 Мар 2018 в 20:51

Просто рекурсивное решение ...

def rec(letters, a):
    return sum(rec(letters[i+1:], a[1:])
               for i, c in enumerate(letters)
               if c == a[0]) if a else 1

Демо-версия :

>>> rec('onerene', 'one')
4
0
Stefan Pochmann 4 Мар 2018 в 23:13