#python #python-3.x #string #recursion #concatenation
#питон #python-3.x #строка #рекурсия #сцепление
Вопрос:
«Учитывая строку как из букв, так и из специальных символов/цифр, используйте рекурсию, чтобы объединить буквы в одну строку и вернуть ее».
Мой код приведен ниже, я все еще изучаю рекурсию и застрял в попытке ее отследить. Я перепробовал кучу разных строк в этом коде, но я знаю, как исправить то, что у меня есть до сих пор:
def decoder(encryptedStr): if len(encryptedStr) != 0: if encryptedStr[0].isalpha() == True: decoded = encryptedStr[0] decoded.join(decoder(encryptedStr[1:])) print(decoded) else: decoder(encryptedStr[1:])
У меня еще ничего не возвращалось, потому что я борюсь с той частью, где я должен присоединять новые буквы к выходной строке. Вместо .join я также попытался:
decoded = decoder(encryptedStr[1:])
но это не работает без Nonetype??
Комментарии:
1. Вы пропускаете
return
else
часть, но алгоритм все равно кажется неправильным.2. Не то чтобы я думаю, что это имеет значение здесь, но без дополнительных шагов типичный ответ, основанный на рекурсии одного символа за раз, будет работать только со строками с 1000 или менее символов.
3. Python-ужасный выбор языка для изучения рекурсии по нескольким причинам. Многократно нарезать струны очень дорого. Даже если у вас есть идея умного и эффективного алгоритма для решения этой проблемы, выражение, подобное
decoder(encryptedStr[1:])
этому, гарантирует, что временная сложность алгоритма не может быть лучше, чем n^2.4. Простым и питоническим решением вашей проблемы без рекурсии было бы
def(encrypted_str): return ''.join(c for c in encrypted_str if c.isalpha())
. Если вы действительно хотите решить эту проблему с помощью рекурсии, я рекомендую выбрать любой другой язык, кроме python.
Ответ №1:
Ваша главная проблема в том , что вы этого не return
сделали, но есть некоторые проблемы с вашим подходом, которые делают это более сложным, чем это необходимо.
При выполнении рекурсии сначала подумайте о том, каково ваше конечное условие и как вы решаете продолжить. Обычно с помощью такого метода вы делаете что-то вроде: 1) обрабатываете одно значение в списке, 2) позволяете рекурсивному методу обрабатывать все остальное, 3) объединяете результаты.
Простым индикатором возврата в конце здесь было бы ничего не возвращать, если строка пуста:
def decoder(encryptedStr): if len(encryptedStr) == 0: return "" ...
Теперь при каждом запуске мы хотим оперировать с одной буквой, а остальное передавать рекурсивному вызову. Игнорируя требование к специальным символам, вы получите что-то вроде этого:
def decoder(encryptedStr): if len(encryptedStr) == 0: return "" first = encryptedStr[0] rest = decoder(encryptedStr[1:]) return first rest
Теперь мы можем справиться с особым случаем, когда мы хотим опустить буквы.
def decoder(encryptedStr): if len(encryptedStr) == 0: return "" first = encryptedStr[0] rest = decoder(encryptedStr[1:]) if not first.isalpha(): first = "" return first rest
И это все, что нужно сделать!
Бонус за некоторый рефакторинг:
def clean(letter): return letter if letter.isalpha() else "" def decoder(encrypted): if len(encrypted) == 0: return "" return clean(encrypted[0]) decoder(encrypted[1:])
Ответ №2:
Здесь есть куча проблем:
- Я не думаю
join
, что в этом случае он делает то, что вы хотите. Если вы хотите добавить несколько строк вместе, просто используйте=
.join
вставил быdecoded
символ между любымиdecoder(encryptedStr[1:])
возвратами. - У вас нет аргумента для
len(encryptedStr) == 0
, поэтому он возвращает значение по умолчаниюNone
. Вот почему вы не можете добавить его результаты кdecoded
.
Ответ №3:
Возвращайтесь немедленно, если вам нечего делать. В противном случае возьмите первую букву, если она соответствует условию, и добавьте результат рекурсивного вызова (где параметром является текущая зашифрованная строка без первого символа).
def decoder(encrypted): if not encrypted: return '' decrypted = encrypted[0] if encrypted[0].isalpha() else '' return decrypted decoder(encrypted[1:]) print(decoder('Abc123rtZ5'))
В результате получается AbcrtZ
.
Бонусная информация (как упоминал @JonSG в комментариях):
Запустите это, print(decoder('A' * 1000))
и вы поймете, почему рекурсия-плохая идея для этой задачи.
Ответ №4:
Каждая рекурсивная функция должна иметь базовое условие, которое останавливает рекурсию, иначе функция вызывает саму себя бесконечно. Чтобы рекурсивно объединить ТОЛЬКО буквы входной строки в одну выходную строку:
some_string = "I2L4o2v3e P;y|t!o#n" def decoder(encryptedStr, decoded = ""): if len(encryptedStr) == 0: # Base condition return decoded if encryptedStr[0].isalpha(): decoded = encryptedStr[0] return decoder(encryptedStr[1:], decoded) # If the char in the index [0] is not a letter it will be sliced out. return decoder(encryptedStr[1:], decoded) print(decoder(some_string))
Выход:
ILovePython