Entendiendo la recursividad en Python

Realmente estoy tratando de entender cómo funciona la recursividad y entender los algoritmos recursivos. Por ejemplo, el siguiente código devuelve 120 cuando ingreso 5, disculpe mi ignorancia, y simplemente no veo por qué.

def fact(n):
    if n == 0:
        return 1
    else:
        return n * fact(n-1)

answer = int (raw_input('Enter some number: '))

print fact(answer)

preguntado el 27 de julio de 12 a las 19:07

Deberá explicarnos qué es exactamente lo que no entiende. ¿Qué crees que debería volver? -

Además, la sangría de su función está ligeramente desviada. -

Ves eso por dentro fact que este mismo fact se llama de nuevo? ¿Y que esta autollamada se detiene cuando n es igual a 0? ¿Y que por cada autodenominación n obtiene uno más bajo? -

Gracias a todas las grandes explicaciones. Definitivamente practicaré todos los días, ya que parece indispensable para escribir algoritmos eficientes. -

4 Respuestas

vamos a caminar a través de la ejecución.

fact(5):
   5 is not 0, so fact(5) = 5 * fact(4)
   what is fact(4)?
fact(4):
   4 is not 0, so fact(4) = 4 * fact(3)
   what is fact(3)?
fact(3):
   3 is not 0, so fact(3) = 3 * fact(2)
   what is fact(2)?
fact(2):
   2 is not 0, so fact(2) = 2 * fact(1)
   what is fact(1)?
fact(1):
   1 is not 0, so fact(1) = 1 * fact(0)
   what is fact(0)?
fact(0):
   0 IS 0, so fact(0) is 1

Ahora recopilemos nuestro resultado.

fact(5) = 5* fact(4)

sustituir en nuestro resultado por fact(4)

fact(5) = 5 * 4 * fact(3)

sustituir en nuestro resultado por fact(3)

fact(5) = 5 * 4 * 3 * fact(2)

sustituir en nuestro resultado por fact(2)

fact(5) = 5 * 4 * 3 * 2 * fact(1)

sustituir en nuestro resultado por fact(1)

fact(5) = 5 * 4 * 3 * 2 * 1 * fact(0)

sustituir en nuestro resultado por fact(0)

fact(5) = 5 * 4 * 3 * 2 * 1 * 1 = 120

Y ahí lo tienes. La recursividad es el proceso de dividir un problema más grande al considerarlo como problemas más pequeños con éxito hasta llegar a un caso trivial (o "base").

Respondido 27 Jul 12, 19:07

Desglose el problema en sus pasos de ejecución.

fact(5)
| 5  * fact(4)
|| 5 * (4 * fact(3))
||| 5 * (4 * (3 * fact(2))
|||| 5 * (4 * (3 * (2 * fact(1))))
||||| 5 * (4 * (3 * (2 * (1 * fact(0)))))
|||||| 5 * 4 * 3 * 2 * 1 * 1
120

Su función simplemente se llama a sí misma, tal como cualquier otra función puede llamarla. Sin embargo, en este caso, su función necesita un punto de parada para que no recurra infinitamente (¡provocando un desbordamiento de pila!). En tu caso es cuando n es 0 (probablemente debería ser 1 en su lugar).

Respondido 27 Jul 12, 20:07

Una función recursiva es aquella que se llama a sí misma y continúa haciéndolo hasta que finaliza la evaluación y se produce un resultado. La clave con la función factorial que tienes arriba es el retorno x * fact(x-1)

Entonces, si ingresa 5, ejecutará 5 * fact (5-1) * fact 4-1) ... Y así sucesivamente hasta que llegue a 0 y luego devuelva 1. Entonces tendrá 5 * 4 * 3 * 2 * 1 que es 120.

Continúa asignando variables en la pila. Entonces, si coloca un número que es demasiado alto, podría resultar en una excepción de desbordamiento de pila. A menos que use algo llamado optimización de llamada de cola (TCO) que convierte la función recursiva en un bucle for y limpia la memoria asignada.

Respondido 27 Jul 12, 19:07

Tenga en cuenta que cada invocación de fact(), ya sea invocada externamente o invocada por sí misma, obtiene su propio conjunto distinto de variables locales.

fact(1) has n of 5
   fact(2) has n of 4
      fact(3) has n of 3
         fact(4) has n of 2
            fact(5) has n on 1
               fact(6) has n of 0

Los más profundos (aquí, fact(6) es el más profundo) se calculan por completo antes de que los niveles por encima de ellos en la pila de llamadas puedan terminar.

So

  • fact(6) devuelve un 1 a fact(5) (caso de rescisión).
  • fact(5) devuelve un 1 a fact(4) (1 * 1)
  • fact(4) devuelve un 2 a fact(3) (2 * 1)
  • fact(3) devuelve un 6 a fact(2) (3 * 2)
  • fact(2) devuelve un 24 a fact(1) (4 * 6)
  • y finalmente fact(1) devuelve 120 (5*24) a quien llama, sea lo que sea.

respondido 19 nov., 19:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.