Попытка решить рекурсию в Python - PullRequest
0 голосов
/ 24 октября 2019

Следующий фрагмент кода - это дебаты, которые я и коллега недавно натолкнули на головы. Я считаю, что программа рекурсивная, тогда как он настаивает, что это не так.

Еще один пост Stackoverflow имеет точный код и обозначен как рекурсивный.

Пожалуйста, кто-нибудь может дать мне объяснение, если он рекурсивный или нет, и почему?

def str_replace_interface():   
    word = input("Enter a word: ")
    if word != 'quit':
        substring = input("Please enter the substring you wish to find: ")
        new_entry = input("Please enter a string to replace the given substring:")
        new_word = word.replace(substring, new_entry)
        print("Your new string is: " + new_word)
        str_replace_interface()

str_replace_interface() 

Упомянутый фрагмент кода может работать отлично, но все еще классифицируется как "рекурсивный"?

1 Ответ

0 голосов
/ 24 октября 2019

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

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

Если мы грубо поместим это в стиль списка маркеров, рекурсивную функцию можно описать следующим образом:

  • Базовые случаи, когда в функции происходят возвраты
  • Функциявызывает себя и передает те же данные, но измененные, «меньшие»

Пока что вставленный вами код делает один из этих двух. Он вызывает себя внутри функции (хотя это не упрощает проблему и не передает данные). Функция не имеет базовых сценариев, с которыми можно решить проблему, но имеет только один случай.

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

Когда вы выполняете файл, содержащий предоставленный код, вызов за пределами определения будет выполняться один раз ,но затем внутри функции он снова вызывает себя, пока пользователь не наберет quit . Хотя кажется, что это необычный forever loop , его можно классифицировать как рекурсивный метод, потому что он вызывает себя внутри определения функции. Теперь, это ужасная рекурсивная функция, потому что вам не нужно, чтобы она была рекурсивной, чтобы работать как задумано. Вы никогда ничего не возвращаете, и каждый раз, когда вы вызываете функцию str_replace_interface () , вы добавляете в стек, что, если вы вызываете его достаточно много раз, может вызвать RecursionError . Давайте сделаем это, чтобы увидеть это в действии. Чтобы добиться этого, я удалю код, который позволяет пользователю выйти, а также удалю ввод, чтобы мне не приходилось набирать слово миллион раз.

def str_replace_interface():   
        str_replace_interface()


str_replace_interface() 

Когда я выполнил, как и ожидалось, я получил следующее:

Traceback (most recent call last):
  File "main.py", line 8, in <module>
    str_replace_interface()
  File "main.py", line 5, in str_replace_interface
    str_replace_interface()
  File "main.py", line 5, in str_replace_interface
    str_replace_interface()
  File "main.py", line 5, in str_replace_interface
    str_replace_interface()
  [Previous line repeated 992 more times]
  File "main.py", line 4, in str_replace_interface
RecursionError: maximum recursion depth exceeded while calling a Python object

Почему? Поскольку функция на самом деле ничего не возвращает, поэтому я упомянул, что рекурсивное выполнение forever loop ужасно. Вы можете достичь того же самого итеративно, как показано ниже:

def str_replace_interface():   
        word = input("Enter a word: ")
        if word != 'quit':
            substring = input("Please enter the substring you wish to find: ")
            new_entry = input("Please enter a string to replace the given substring: ")
            new_word = word.replace(substring, new_entry)
            print("Your new string is: " + new_word)
            return True
        return False    

while str_replace_interface():
  pass

Здесь мощность forever loop происходит на основе возвращаемого значения после выполнения функции,Вы не добавляете в стек каждый вызов, потому что функция фактически возвращается. Что произойдет, если мы снова и снова будем вызывать непрерывный вызов, как для рекурсивного? Ну, ответ ничто. У тебя будет вечная петля ... ну, навсегда. Но вы не получите Recursive Error , потому что функция выполняется и возвращается перед повторным вызовом. Попробуйте:

def str_replace_interface():   
        return True

while str_replace_interface():
  pass 

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

Надеюсь, это поможет вам разобраться.

...