Es cierto que todos los algoritmos iterativos se pueden describir de forma recursiva. De hecho, los programadores funcionales definen la iteración como el caso especial de recursión donde todas las llamadas recursivas son recursivas de cola . La traducción es puramente mecánica: simplemente convierta todos los estados variables en argumentos de función. Por ejemplo,
def foo(): s = 0 i = 0 while i < 10: s = s + i i = i + 1 return s print foo()
puede reescribirse como
def foo(s, i): if i < 10: return foo(s + i, i + 1) return s print foo(0, 0)
¿Podemos revertir esta transformación para convertir un algoritmo recursivo en uno iterativo? Bueno, eso depende de lo que llames “iterativo”.
- ¿Ser bueno en matemáticas ayuda en la programación?
- ¿En qué secuencia se debe aprender la estructura de datos, el algoritmo y las matemáticas discretas?
- Estoy interesado en algoritmos. Planeo hacer una maestría en informática teórica en una de las 20 mejores universidades. ¿Cuán significativamente ayudará a hacerme digno de la industria?
- Cómo interpretar 'lift' y 'odds ratio' en las reglas de asociación
- ¿Podría alguien ayudarme a determinar qué camino en mi educación se adaptaría mejor a mis intereses?
Dada una función recursiva general:
def fib(n): if n <= 1: return n return fib(n - 1) + fib(n - 2) print fib(10)
siempre podemos convertirlo en una función recursiva de cola reescribiéndolo en un estilo de paso de continuación :
def fibc(n, cont): if n <= 1: return cont(n) return fibc(n - 1, lambda a: fibc(n - 2, lambda b: cont(a + b))) print fibc(10, lambda x: x)
y ahora podemos llevar todas las llamadas recursivas de cola a un bucle de evaluación externo:
def fibi(n, cont): if n <= 1: return (cont, [n]) return (fibi, [n - 1, lambda a: (fibi, [n - 2, lambda b: (cont, [a + b])])]) (f, args) = (fibi, [10, None]) while f is not None: (f, args) = f(*args) [ret] = args print ret
Esencialmente, hemos reificado la pila de recursión como una estructura de datos explícita (aquí una que está hecha de cierres
, pero podríamos fácilmente salir de estructuras más tradicionales como listas). El código resultante ciertamente usa un ciclo iterativo, y podría describirse como “no recursivo” en el sentido de que nunca usa más de un nivel de la pila del lenguaje. Pero es difícil argumentar que esta transformación mecánica cuenta como algo más que llevar la recurrencia a un nivel diferente de interpretación. lambda
Si comienza con un algoritmo recursivo que no es recursivo de la cola, puede ser necesario reescribirlo como un algoritmo “verdaderamente iterativo”, si es que es posible.
(a, b) = (0, 1) for i in xrange(10): (a, b) = (b, a + b) print a