2012-01-02 16 views
5

Estaba leyendo las respuestas que obtuvieron una insignia de "anulación" y encontré una pregunta con respecto a la recursión donde la OP no se molestó en hacer gran parte de su tarea desde el principio. Además de algunas respuestas realmente divertidas, @machielo publicó an answer en python que tuve que ejecutar en mi máquina para controlarlo. Todavía no lo entiendo.No entiendo este uso de la recursión

def recursive(x): 
    if x > 10: 
     print recursive(x/10) 
    return x%10 

>>> recursive(2678) 
2 
6 
7 
8 

probé mi primera suposición, pero sé que está mal

>>> 2678/10 
267 
>>> 267/10 
26 
>>> 26/10 
2 
>>> 2%10 
2 

bien ... eso es los dos. ¿Cómo evalúa esto la salida de los otros números en x?

EDITAR

Es la declaración de print que no consigo aquí. He modificado el código como tal:

>>> def recursive(x): 
if x > 10: 
    print x 
    print recursive(x/10) 
return x%10 

>>> #I will comment the interpreter session here... 
>>> recursive(2345) 
2345 # first feed in...print the raw number `x` 
234 # 2345/10 does equal 234...the 5 is being held back somewhere... 
23 # and each pass through the recursive loop removes the last digit... 
2 # but where was it being stored at, so that each evaluation of 
3 # x > 10 finally started returning False 
4 # and returns the number, exiting the function 
5 # ... 

Estoy pensando que durante cada ejecutar a través de la llamada a print recursive(x/10) crea un nuevo objeto de función, cada uno con su propio nuevo caso base de la marca y de entrada ...

Otra pista, ¿alguien?

FINALMENTE

Gracias a todos. Siento que entiendo esto ahora ... el truco no fue tanto print como lo fue x%10. 2345%10 == 5 ...

>>> def recursive(x): 
print "Raw `x`:", x 
if x > 10: 
    print "Recurse `x`:", x 
    print recursive(x/10) 
print "Last `x`:", x  
return x%10 

>>> recursive(2345) 
Raw `x`: 2345 
Recurse `x`: 2345 
Raw `x`: 234 
Recurse `x`: 234 
Raw `x`: 23 
Recurse `x`: 23 
Raw `x`: 2 
Last `x`: 2 
2 
Last `x`: 23 
3 
Last `x`: 234 
4 
Last `x`: 2345 
5 

Además, el crédito a todo el que entraba y actualizada la respuesta inicial que I previously linked to ... Estoy a punto de upvote su comentario:

>>> def recursive(x): 
if x >= 10: 
    print recursive(x/10)  
return x%10 
+0

Creo que no entiendo totalmente la pregunta. ¿Qué quieres decir con "cada número en' x' "? –

+0

No quiero enturbiar mi pregunta con todas mis malas suposiciones ** pero ** ... al reemplazar 'print recursive (x/10)' con 'return recursive (x/10)' empujará el caso base hacia el primer pase de recursión. – Droogans

+0

su ejemplo no produce esa salida para mí – joaquin

Respuesta

11

creo que la adición de unos pocos print declaraciones que es realmente útil:

def recursive(x): 
    print '[start] recursive({0})'.format(x) 
    if x > 10: 
    print recursive(x/10) 
    print '[return] recursive({0}) = {1}'.format(x, x%10) 
    return x%10 

print recursive(2678) 

la salida es:

[start] recursive(2678) 
[start] recursive(267) 
[start] recursive(26) 
[start] recursive(2) 
[return] recursive(2) = 2 
2 
[return] recursive(26) = 6 
6 
[return] recursive(267) = 7 
7 
[return] recursive(2678) = 8 
8 
+0

gran respuesta, realmente – joaquin

+0

@joaquin Gracias, lo agradezco. – jcollado

+0

Copié tu formato y lo pellizqué ligeramente para obligarme a construirlo de memoria. ¡Buen ejemplo! – Droogans

3

impresiones Esta función fuera los dígitos del número.

funciona así:

def recursive(x): 
    if x > 10: 
    # Divide x by 10 and round down. This chops off the last decimal place. 
    # Now feed that new x without the last decimal place back into recursive() 

    # return x's last digit 

Básicamente, no va a print nada hasta x es un número de un solo dígito.

La parte que le produce confusión es probablemente la razón por la que imprime cada posición decimal en ese orden. Esto sucede porque, mientras la función se repite, la función principal aún se está ejecutando.

Intenta expandir el código para ese número único.


Editar: estoy confundiendo a mí mismo también.

el código llama printantesreturn, lo que significa que cuando el nivel última de acabados de recursividad, el segundo al último imprime el primer dígito. Lo mismo aplica para las siguientes capas.

+0

Bien @Blender, escribiré mi horrible intento de imitar un diagrama de pila. – Droogans

5

Pasando a través de su ejemplo en pseudocódigo (número de guiones indica nivel de recursividad):

-call recursive(2678) 
--2678 > 10, call recursive(267) 
---267 > 10, call recursive(26) 
----26 > 10, call recursive(2) 
-----return 2%10 (which is 2) 
----print 2, then return 26 % 10 (which is 6) 
---print 6, then return 267 % 10 (which is 7) 
--print 7, then return 2678 % 10 (which is 8) 
-return 8 
+0

Así que estás diciendo que la declaración 'print' no se evalúa hasta mucho más tarde en el ciclo recursivo, y aun así ... ¿en realidad no muestra los resultados? ¿Es eso lo que quieres decir con 'imprimir 2, luego devolver 26% 10'? Tienes la última línea para ser 'return 8', y es por eso que estoy pensando en esto. – Droogans

+0

@Droogans Creo que es correcto. el último 8 está impreso por la consola – joaquin

+0

No es que no se haya evaluado. La sentencia de impresión no se puede resolver todavía porque sigue llamando al método recursivamente. Los valores no se pueden resolver hasta que devuelve un valor en la parte inferior, por lo tanto, la recursión puede verse como la respuesta burbujeante. – Jordan

1

Tenga en cuenta la pila de llamadas al considerar la recursión . La llamada recursiva está empujando todo recursive() función llama a la pila antes de que algo se imprime así que lo que se termina con la pila es

recursive(2) # end condition is met so returns 2%10 
recursive(26) 
recursive(267) 
recursive(2678) # the initial call 

una vez que la condición final se alcanza el 2% 10 (2) se devuelve a la anterior declaración de impresión de la función e impresa, luego esa función devuelve 26% 10 (6), y esto continúa hasta que hayan regresado todas las llamadas a la función recursiva en la pila. El resultado es esta serie de llamadas de impresión:

print 2 
print 6 
print 7 
8 

8 no se imprime realmente; simplemente se devuelve, lo cual está bien para el intérprete. Si quería asegurarse de que se imprimiera, por ejemplo, en un script de Python, llamaría al print recursive(2678)

Cuestiones relacionadas