Использование рекурсии для объединения ТОЛЬКО букв входной строки в одну выходную строку

#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