Переписать рекурсивную функцию без использования рекурсии
-
09-10-2019 - |
Вопрос
Я переписываю какой-то существующий код в настройке, где рекурсивные вызовы не легко реализованы и не желательны. (А в Фортране 77, если вы должны знать.) Я думал о том, чтобы сделать стек с нуля, чтобы отслеживать необходимые звонки, но это кажется Kludgy, и я бы предпочел не выделить память в массив в случаях, когда Рекурсия не глубокая. (Я не уверен, что Fortran 77 поддерживает размывание динамического массива.)
Любые другие предложения для общего решения о том, как предпринять очевидно рекурсивное функцию и переписать его нерешительно, не тратя пространство на стеке?
Большое спасибо, старый McSt
Решение
Если ваш код использует рекурсию хвоста (то есть функция возвращает результат каждого рекурсивного вызова непосредственно без какой-либо другой обработки), то можно домельно переписать функцию без стека:
function dosomething(a,b,c,d)
{
// manipulate a,b,c,d
if (condition)
return dosomething(a,b,c,d)
else
return something;
}
В:
function dosomething(a,b,c,d)
{
while (true)
{
// manipulate a,b,c,d
if (condition) continue;
else return something;
}
}
Без рекурсии хвоста, используя стек (или аналогичное промежуточное хранение) - единственное решение.
Другие советы
Классическая рекурсивная функция, которая может быть записана в виде петли, является функцией Fibonacci:
function fib(n)
{
// valid for n >= 0
if (n < 2)
return n;
else
return fib(n-1) + fib(n-2);
}
Но без воспоминания это принимает операции O (Exp ^ n) с пространством O (n).
Это может быть переписано:
function fib(n)
{
if (n < 2)
return n;
var a = 0, b = 1;
while (n > 1)
{
var tmp = a;
a = b;
b = b + tmp;
n = n - 1;
}
return b;
}
Но это включает в себя знание того, как работает функция, не уверена, что она может быть обобщена в автоматическом процессе.
Большинство рекурсивных функций могут быть легко переписаны в виде петлей, чтобы тратить пространство - это зависит от функции, поскольку многие (но не все) рекурсивные алгоритмы фактически зависят от такого рода хранения (хотя версия петли обычно более эффективна в этих случаях. слишком).