¿Alguien puede ayudarme a entender cómo funciona este código?

Si algún número A es MCD de B y C, eso significa que los grupos de elementos B y C se pueden dividir en varios grupos, de modo que cada grupo contenga elementos A. ¿Suficientemente fácil? Miremos más de cerca a esos grupos.

Si los colocamos uno al lado del otro (es decir, agregamos B y C), ¿todavía se puede dividir en grupos de elementos A? ¿Correcto? ¿Qué pasa con la resta? Bueno, debido a que tanto B como C se pueden dividir en grupos de A, la resta se convierte en eliminar varios grupos de elementos A, dejando el resto que aún se puede dividir en grupos de elementos A.

Ahora, veamos la división. Si dividimos B con C, eso significa simplemente crear grupos de grupos: tomar grupos de elementos A y ponerlos en una misma línea hasta que lleguemos a grupos C y continuar agregando líneas hasta obtener un total de elementos B. Cuando estamos a punto de agregar la última línea, es posible que no esté completa. Esa última línea, incompleta, representa el resto. Tenga en cuenta que hasta ahora hemos hecho todo en los grupos de elementos A. Por lo tanto, el resto se puede dividir en grupos donde cada grupo contiene elementos A.

Eso es matemática informal detrás de esto. Intenta visualizar grupos como montones de piedras.

Probemos un ejemplo. Calcular MCD (36,60). Supongo que son las 12.

Los nombres de las variables en la declaración son los nombres de las entradas. Los nombres de las variables en la línea 2 son sus usos.

Entonces mcd (u = 36, v = 60) -> v = 60, u% v = 36

-> mcd (u = 60, v = 36) -> v = 36, u% v = 24

-> mcd (u = 36, v = 24) -> v = 24, u% v = 12

-> mcd (u = 24, v = 12) -> v = 12, u% v = 0

-> mcd (u = 12, v = 0) -> devolver u = 12; y ahora sube la pila de llamadas hasta llegar a la cima.

Entonces, no es un algoritmo con el que estoy familiarizado, pero el principio aquí es tratar de encontrar el número entero más grande que, cuando se divide en cada uno de los 2 números enteros dados, tenga un resto de 0 en ambos casos.

a menudo, la mejor manera de explorar código desconocido es ejecutar un ejemplo. Así que intentemos llamarlo con 6 y 9 esperando la respuesta 3.

entonces, mcd (6, 9): u = 6, v = 9. v no es 0 así que ahora llame:

mcd (9, 6% 9 = 6). v no es 0, así que ahora llame:

mcd (6, 9% 6 = 3). v no es 0, así que ahora llame:

mcd (3, 6% 3 = 0). ahora, v es 0, por lo que 3 se devuelve al llamador original.

No intentaré explicar por qué esto funciona, pero si trabajas con otros ejemplos, verás que funciona.

Sobre la pregunta específica de por qué la llamada recursiva es gcd (v, u% v), bueno, no tiene que ser así. Tenga en cuenta que es válido que la persona que llama inicialmente llame a gcd (6,9) o gcd (9,6) y espere la misma respuesta en ambos casos. En mi ejemplo, la primera llamada simplemente invierte los argumentos para obtener la más grande primero. Esto significa que escribir el algoritmo como:

Int mcd (u, v) {

Devuelve u == 0? v: mcd (v% u, u);

}

Funcionaría igual de bien. Por cierto, prefiero el == aquí al! = En el original porque es más fácil de leer. Esta segunda versión es más rápida cuando u

Tienes que entender un poco de teoría de números.

Digamos que d es el mcd de u y v. Significa u = m * d y v = n * d para algunos m, n tal que mcd (m, n) = 1. Sin pérdida de generalidad podemos suponer u> v.

Entonces tenemos, u = p * v + k para algunos py k.

=> m * d = p * n * d + k

=> d | k, yk es el resto cuando u se divide por v.

QED

More Interesting

¿Cuáles son todas las estructuras de datos que conoce? ¿Cuál de estos usas con frecuencia? Agrúpelos en "Básico" y "Avanzado".

¿Se requiere un buen conocimiento de la estructura de datos y algoritmos para saltar a la codificación competitiva?

¿Las compañías aéreas han mejorado la eficiencia de sus algoritmos de sobreventa?

¿Qué es recursivo en matemáticas?

¿Cómo puede un programador competitivo construir cosas solo por algoritmo y un lenguaje y nada sobre la web?

¿Qué hay de malo con este código básico de Python?

¿Qué es NP-hard y NP-complete?

¿Cómo puede funcionar un algoritmo con un conjunto de datos pequeño pero da valores incorrectos en un conjunto de datos más grande?

¿Qué es un algoritmo recursivo (pseudocódigo) que calcula la suma de los primeros enteros positivos impares?

¿Cómo se puede averiguar el número de veces que se repite una palabra en una cadena usando Java?

Cómo instalar accesorios de compresión en tubos de plástico

¿Qué pasaría si más personas se dieran cuenta de que la Ley podría entenderse como una serie de algoritmos sociales en un programa que se resiste a la compilación?

¿Cuáles son las aplicaciones más prácticas (vida cotidiana) del algoritmo de agrupación de k-means? ¿Cómo se ha utilizado exactamente k-means en estas aplicaciones?

¿Cuál es la lógica detrás del algoritmo de escaneo de Graham para casco convexo?

¿Dónde puedo encontrar un algoritmo de relevancia marginal máxima en Python para la eliminación de redundancia en dos documentos?