Нет, для этого нет общего и простого метода, как для хвостовой рекурсивной задачи. Это верно, даже если у вас есть 1 рекурсивный вызов в конце, но функция не является хвостовой рекурсивной (например, return 5+foo(x)
). Вам придется явно поддерживать стек, и тогда он будет работать даже для случаев с более чем двумя рекурсивными вызовами в конце.
Чтобы понять почему, обратите внимание, что каждая отдельная переменная в хвостовой рекурсивной функции (то есть параметры и локальные переменные) может иметь не более одного возможного значения в любой данный момент. Таким образом, вам никогда не нужно поддерживать более одной их версии в оперативной памяти. Поскольку в момент следующего рекурсивного вызова хороший компилятор уничтожит их текущую версию и выделит новую версию в том же месте, в котором они находятся в настоящее время. Поэтому в основном это просто изменение переменной, а не выделение новых.
Так что для нормальных рекурсивных функций без гарантии "max 1 version" объявите стек перед основным циклом. Каждый элемент в нем будет кортежем всех параметров. Внутри цикла получите последний элемент стека (и удалите его из стека). Затем просто скопируйте / вставьте ваше тело функции внутри цикла. Однако, кроме следующего рекурсивного вызова, создайте элемент, содержащий все значения параметров этого вызова, и поместите его в стек. Ваш код изменен:
A = [] #your initial 'L'
stack = [(2,4,A)] #push values of initial call
while stack:
x,y,L = stack.pop()
print(x,y)
if x < y:
x += 1
else:
x -= 1
y -= 1
if y > 0:
L.append(x)
stack.append((x, y, L))
stack.append((x - 1, y - 1, L))
Однако он будет работать только тогда, когда порядок рекурсивного вызова не имеет значения, как для dfs. В противном случае у меня есть идея для «внутреннего стека», но этот ответ уже становится слишком длинным.