c# recursion workflow pow

c# - ¿Cuál es el flujo de trabajo de la función Pow(x, y)?



recursion workflow (5)

Ese método básicamente calcula " x elevado a la potencia de y ". Lo hace de manera recursiva .

Primero, define un caso base : cualquier cosa elevada a la potencia de 0 es 1.

Luego, define qué hacer en todos los demás casos: x * Pow(x, y - 1) . Suponiendo que y es grande, ¿qué es x * Pow(x, y - 1) ? Es x * x * Pow(x, y - 2) , que a su vez es x * x * x * Pow(x, y - 3) . ¿Ves el patrón aquí? Eventualmente, llegará al punto donde el segundo argumento, y - N , es 0, que como hemos establecido, es 1. En ese punto, ¿cuántas x * tenemos? Exactamente y .

Veamos esto en acción para Pow(2, 5) :

Pow(2, 5) 2 * Pow(2, 4) 2 * 2 * Pow(2, 3) 2 * 2 * 2 * Pow(2, 2) 2 * 2 * 2 * 2 * Pow(2, 1) 2 * 2 * 2 * 2 * 2 * Pow(2, 0) 2 * 2 * 2 * 2 * 2 * 1

De ahí el resultado 32.

Estoy pasando por los cursos "sololearn" y udemy para tratar de aprender C #. Estoy haciendo los desafíos, pero no pude entender cómo el código siguiente resultó con 32 (como en 32 es la respuesta correcta aquí y estoy tratando de averiguar por qué). ¿Puede alguien explicarme este proceso? Creo que el método que se llama a sí mismo me está arrojando.

static double Pow(double x, int y) { if (y == 0) { return 1.0; } else { return x * Pow(x, y - 1); } } static void Main() { Console.Write(Pow(2, 5)); }

Por favor, disculpe mi mala codificación. Estoy tratando de hacerlo en dispositivos móviles, lo cual es difícil, la respuesta fue 32. ¿Alguien puede explicar por qué?

Editar: Aplogies aquí es cómo trabajo a través de él. Pase 2 y 5 a Pow, verifique si y == 0 que es falso, ahora es y == 5 por lo que la fórmula x * pow(x, y-1) estará activa. X sigue siendo 2, y ahora es 4, lo que significa que vuelve a fallar la comprobación de si es igual a 0, este ciclo continúa hasta que devuelve el 1.0, x ha permanecido en 2, entonces 2 * 1.0 = 2 y no 32?


Hola, su recursión y se repite hasta y=1 , luego devuelve 2 , luego devuelve 4, 8, 16, 32 al final. 2^5=32


Lo primero que debe tener en cuenta es que NO es así como normalmente implementaría una función de potencia. Se hace de esta manera para demostrar la recursividad.

Una vez dicho esto, veamos qué sucede cuando llamas a Pow(2, 5) :

Pow(x = 2, y = 5) -> return 2 * Pow(2, 4) <- 2 * 16 = 32 Pow(x = 2, y = 4) -> return 2 * Pow(2, 3) <- 2 * 8 = 16 Pow(x = 2, y = 3) -> return 2 * Pow(2, 2) <- 2 * 4 = 8 Pow(x = 2, y = 2) -> return 2 * Pow(2, 1) <- 2 * 2 = 4 Pow(x = 2, y = 1) -> return 2 * Pow(2, 0) <- 2 * 1 = 2 Pow(x = 2, y = 0) -> return 1 (because y == 0) <- 1

Para leer esta representación de la pila de llamadas recursivas, trabaje de arriba a abajo mirando cómo cambian los argumentos; luego trabaje hacia arriba desde abajo hacia arriba mirando los valores de retorno (que indico con <- ).


Ok, así que repasemos todo el asunto.

En primer lugar, una función estática es aquella que se puede invocar sin necesidad de instanciar un objeto. Hay una firma que comparten todos los objetos de la misma clase. El doble es un tipo dentro de C # y aparece aquí para mostrar cuál será el tipo de salida final de la función. Pow es el nombre de la función, double x, int y son parámetros descritos por su tipo (no muy bien nombrados, pero lo dejaremos para otro día)

Entonces x es un número e y es el poder de ese número. Aquí hay un condicional para verificar dos resultados. Si y es 0, entonces la respuesta es siempre 1, matemática simple. De lo contrario, la función realiza la aritmética utilizando recursividad (se llama a sí misma nuevamente hasta que cumpla una condición de terminación). La razón por la que obtenemos 32 es porque 2x2x2x2x2 = 32. Es 2 a la potencia de 5.

Supongo que sabes qué son main y console.write.


Para poder comprender cada acción en este comportamiento recursivo, registre todos los detalles para ver qué está sucediendo realmente. Como :

using System; namespace Tester { class test { // What Pow actually does: static double logPow(double x, int y) { var old = x; // Hold the x for (var i = 0; i < y; i++){ // do it y times x = old * x; // Multiply with it''s first self } return x; } static int counter = 0; static double Pow(double x, int y) { counter++; Console.Write("Recursive action[" + counter + "] Y status ["+ y +"] : "); if (y == 0) { Console.Write("return 1.0 = " + logPow(x, y) + " /n"); return 1.0; } else { Console.Write("return " + x + " * Pow(" + x + ", " + y + " - 1) = " + logPow(x,y-1) + " /n"); return x * Pow(x, y - 1); } } static void Main() { Console.Write("Last Result : " + Pow(2, 5)); } } }

Lo que da el resultado:

Recursive action[1] Y status [5] : return 2 * Pow(2, 5 - 1) = 32 Recursive action[2] Y status [4] : return 2 * Pow(2, 4 - 1) = 16 Recursive action[3] Y status [3] : return 2 * Pow(2, 3 - 1) = 8 Recursive action[4] Y status [2] : return 2 * Pow(2, 2 - 1) = 4 Recursive action[5] Y status [1] : return 2 * Pow(2, 1 - 1) = 2 Recursive action[6] Y status [0] : return 1.0 = 2 Last Result : 32

Puede depurar su código mirando estos detalles. También puedes divertirte usando este enlace: https://onlinegdb.com/Bysbxat9H