Это сложный вопрос, чтобы ответить полностью авторитетным способом - я думаю, что у разных людей разные способы мышления о рекурсии. My Способ мышления о рекурсии - заставить себя думать очень дисциплинированным, абстрактным образом о том, что такое функция. Функция - это просто отображение. Это просто в принципе, но легко забыть на практике, особенно если вы привыкли думать в императивных терминах, то есть думать о программах как наборах инструкций.
Забудьте о инструкции на минуту, и думать о функции факториала в наиболее абстрактной форме:
X Y
--------------------
0 ------> 1
1 ------> 1
2 ------> 2
3 ------> 6
4 ------> 24
5 ------> 120
6 ------> 720
...
Не беспокойтесь сейчас о том, как вычислить это. Подумайте только об абстрактном картографии. Теперь давайте подумаем о том, как сделать рекурсивную версию этой функции. Что нам нужно? Ну, нам нужна функция, которая создает другое сопоставление, а не отображение от [1, 2, 3, ...]
к факториалам, а отображение от одного значения от Y
к следующему. Другими словами (с использованием нижнего регистра в настоящее время):
x y
--------------------
1 ------> 1
1 ------> 2
2 ------> 6
6 ------> 24
24 ------> 120
120 ------> 720
720 ------> 5040
...
Теперь давайте подумаем о том, как рассчитать это. Сразу появляется проблема: 1
карты до 1
в первый раз и до 2
второй. Поэтому мы знаем, что нам нужно написать специальный случай, чтобы отличить эти два. Но для остальных это довольно просто, не так ли? Просто умножьте x
на свою позицию в списке. Таким образом, это означает, что для всех этих частей отображения, нам нужно знать только две вещи: x
и его position
в списке:
def factorial_recurrence(x, position):
return x * position
Обратите внимание, что эта функция теперь имеет два аргумента, так что это на самом деле немного отличается функция, чем выше:
x, p y
------------------------
1 0 ------> 1
1 1 ------> 2
2 2 ------> 6
6 3 ------> 24
24 4 ------> 120
120 5 ------> 720
720 6 ------> 5040
Это показывает совершенно ясно, как мы можем различать два отображений из 1
. Теперь нам просто нужно придумать способ получить информацию о позиции. Так получилось, что position
совпадает с значением X
. Таким образом, один простой способ - использовать цикл. Здесь мы заботимся о X == 0
, просто установив x
в 1
и начать наш цикл в 1
вместо 0
:
def factorial(X):
x = 1
for position in range(1, X + 1):
x = factorial_recurrence(x, position)
return x
Теперь обратите внимание, что стоимость x
здесь находится передаются в factorial_recurrence
, а затем результат сохраняется как x
.
Итак, что здесь происходит, так это то, что выход функции возвращается в функцию. Вот большой разбор:
Это рекурсия!
Это, в критическом смысле, уже рекурсивный алгоритм. Это просто, что представление здесь наизнанку, и функция также включает в себя информацию position
из-за рекурсивного процесса.Для того, чтобы увидеть, что я имею в виду, посмотрите на это:
def even_factorial(X):
x = 1
for position in range(2, X + 1, 2):
x = factorial_recurrence(factorial_recurrence(x, position - 1), position)
return x
Это дает тот же результат, как и factorial
для каждого четного значения X
. (Он дает результат X - 1
для нечетных значений X
.) И нам не нужно останавливаться на достигнутом. Мы можем сделать то же самое для каждого третьего значения X
(вспыхивают вложенности для ясности):
def third_factorial(X):
x = 1
for position in range(3, X + 1, 3):
x = factorial_recurrence(
factorial_recurrence(
factorial_recurrence(
x,
position - 2
),
position - 1
),
position
)
return x
Теперь сделайте то же самое для каждого 4-го, каждый 5-й, и так далее. Если вы продолжите этот процесс, то для любого заданного X
вы в конечном итоге создадите функцию, которая не вернет ничего, кроме 1
, до тех пор, пока вы не пройдете X
, а затем, когда вы пройдете X
, вы получите факториал X
.
На данный момент трюк рекурсии состоит в том, чтобы понять, что мы можем автоматизировать этот процесс выключения петли наизнанку, получив вызов factorial
. Каждый раз, когда вызывается factorial
, он просто гнездится еще один вызов factorial_recurrence
внутри последнего - если только X
не равен 0, и в этом случае он возвращает 1
, завершая последовательность вложенных вызовов.
def factorial(X):
if X == 0:
return 1
else:
return factorial_recurrence(factorial(X - 1), X)
Так что это своего рода сложно думать о рекурсии, но его значение в том, что она показывает, очень четко, отношения между абстракцией рекурсивных функций и их конкретной реализации в императивного кода.
Мне кажется, вам нужно научиться математике и компьютерной системе. Рекурсия - это природа вселенной, я думаю. – HuStmpHrrr
http://interactivepython.org/courselib/static/pythonds/Recursion/recursionsimple.html – dm03514