Vlad_Ki
Я вот не могу понять до какого момента вычисляется возвращаемое значение. Ведь тут на лицо рекурсия. Буду рад, если кто то объяснит. Вообще удивился когда эта функция мне вернула значение.
Оно всегда вычисляется, на каждом шаге. Не может быть такого, что функция не вернёт число, где бы она не была вызвана.
Чтобы понять рекурсию, представляй, что функция вызывает не саму себя, а вызывает совершенно другую функцию, которая просто на неё очень сильно похожа. Представь, что у тебя записаны 100 функций и все они похожи друг на друга так, что выглядят одинаково. Тогда первая функция вызывает вторую, вторая вызывает третью, третья вызывает четвёртую и так далее. Каждая функция что-то вычисляет и передаёт этот результат функции, вызывающей её.
Vlad_Ki
Я вот не могу понять до какого момента вычисляется возвращаемое значение.
Есть такой приём при работе с рекурсией: задайся вопросом “Что делает функция на максимальной глубине?”
Берём вариант от
JOHN_16 и пытаемся его понять через наш метод: сначала мы ищем, что происходит на самом глубоком уровне; затем мы ищем, что происходит на уровне, который находится на один выше самого глубокого уровня; далее мы эти уровни связываем между собой через возвращаемое значение, которое возвращается с самого глубокого уровня на уровень, который на один выше самого глубокого уровня. Так мы поймём весь рекурсивный процесс, какая бы глубина у него ни была.
(Слово factaral неправильное, нужно использовать слово factorial, но мы его не будем менять, оставив как есть, для сохранения условий более близкими к условиям дикого мира. В диком мире программ ещё и не такое увидишь. Это просто один из индикаторов плохого знания английского языка, которое выливается в кучу таких ошибок в коде, которые его затуманивают для чтения и понимания другими участниками разработки.)
def a_factaral(n):
return (n > 0 and ((n == 0 and 1) + n) * a_factaral(n - 1)) + (n == 0 and 1)
Ищем вызов функции в функции и видим, что n уменьшается на единицу
Если мы подадим 10, то на максимальной глубине n будет равно нулю.
(Мы видим, что при всех значениях выше нуля поведение функции будет одно и то же, а при нуле оно станет каким-то другим, поменяется.)
Так мы понимаем, что ноль - это, скорее всего, самый глубокий уровень данной рекурсии.
Подставляем везде ноль вместо n
def a_factaral(0):
return (0 > 0 and ((0 == 0 and 1) + 0) * a_factaral(0 - 1)) + (0 == 0 and 1)
На максимальной глубине получится
Дальше 0 > 0 оно не пройдёт в левой части операции +, а результат сравнения 0 > 0 равен False. Поэтому возвращаемое значение функции на максимальной глубине равно единице. Вызова a_factaral(-1) не произойдёт, поэтому мы его не считаем уровнем, который глубже нулевого. Следовательно, самый глубокий уровень данной рекурсии находится на нулевом аргументе функции. И значение функции на этом уровне равно единице, так как False + 1 = 1.
Теперь возьмём на один уровень выше уровня максимальной глубины
На нём n равно единице, заменяем все n на единицы
def a_factaral(1):
return (1 > 0 and ((1 == 0 and 1) + 1) * a_factaral(1 - 1)) + (1 == 0 and 1)
Мы видим, что можем заменить вызов функции на число, так как знаем значение функции на максимальной глубине, где n равно нулю, так как вычислили его только что до этого
def a_factaral(1):
return (1 > 0 and ((1 == 0 and 1) + 1) * 1) + (1 == 0 and 1)
На этом уровне (на один выше самого глубокого) получится
return ((False + 1) * 1) + False
Поэтому возвращаемое значение функции на этой глубине тоже равно единице.
То есть a_factoral(0) = 1 и a_factoral(1) = 1
Для понимания данного процесса рекурсии этого достаточно - рассмотрения двух уровней глубины (самого глубокого и на один выше самого глубокого).
Просто для того, чтобы убедиться в своей правоте, мы можем рассмотреть ещё один уровень выше.
Если мы рассмотрим всё то же самое для двойки, то мы получим a_factoral(2) = 2
def a_factaral(2):
return (2 > 0 and ((2 == 0 and 1) + 2) * a_factaral(2 - 1)) + (2 == 0 and 1)
Заменив вызов функции a_factoral(2 - 1), который равен a_factora(1), который равен 1, мы получим возвращаемое значение для двойки
return (2 > 0 and ((2 == 0 and 1) + 2) * 1) + (2 == 0 and 1)
Упростим его
return ((False + 2) * 1) + False
То есть a_factoral(2) = 2
Так мы убедились ещё раз, что значение меняется аналогично в результате рекурсивного процесса. Обычно всё изучение рекурсивной функции (которая уже есть или которую нужно сделать) заканчивается на двух уровнях глубины. Третий уровень глубины можно не рассматривать, так как он ничего нового не даёт в плане знаний; он просто повторяет то же самое, что уже известно.
Вот обычно при составлении (или анализе) рекурсивной функции достаточно рассмотреть два уровня: самый глубокий и на один уровень выше от самого глубокого. На самом глубоком уровне можно вычислить значение функции без каких-либо допольнительных вызовов. А на уровне на один выше от самого глубокого можно отследить передачу значения из внутреннего вызова во внешний по отношению к нему вызов и понять, правильно ли это возвращаемое значение используется в вычислениях.
tags: recursion