Calcular mcd. Compila bien pero no corre

Iniciado por jairogon, 1 Julio 2010, 03:52 AM

0 Miembros y 2 Visitantes están viendo este tema.

nicolas_cof

Cita de: czealt en  1 Julio 2010, 21:28 PM
Citar
... si te fijas bien en el codigo no seria lo mismo hacer un while que un do-while ya que con este ultimo estarias ejecutando 3 sentencias totalmente innecesarias.

Bueno, eso solo sucederia cuando uno de los números dados como entrada es cero lo cual no es una entrada válida para el programa. Si se ha de verificar por la entrada válida, ¿porqué no tambien verificar por la entrada de números negativos?

czealt, porque pensas que se tendria que verificar por la entrada de numeros negativos?

CitarEl máximo común divisor (abreviado mcd o m.c.d.) de dos o más números enteros es el mayor número que los divide sin dejar resto. - Wikipedia

Que se ingrese como entrada el valor 0, no quiere decir que este sea una entrada invalida para el programa, ya que por definicion seria correcto. Yo lo que te queria decir con respecto del do-while es que ejecutarias 3 sentencias totalmente innecesarias que no aportan ningun valor al objetivo del programa. Por eso es mejor usar el while y evitar ejecutar ese bloque de codigo.

Salu10.

MIG80

OK nicolas_cof si 0 es un valor válido como entrada para el programa que calcula el M.C.D de dos números dime cuanto es el MCD de 0 y 1?

nicolas_cof

Cita de: czealt en  2 Julio 2010, 00:00 AM
OK nicolas_cof si 0 es un valor válido como entrada para el programa que calcula el M.C.D de dos números dime cuanto es el MCD de 0 y 1?

1

Salu10.

MIG80

Muy bien (señido a la definición, como debe de ser).

Saludos.

nicolas_cof

Cita de: czealt en  2 Julio 2010, 00:35 AM
Muy bien (señido a la definición, como debe de ser).

Saludos.

function mcd(a, b)
   while b ≠ 0
      t := b
      b := a mod b
      a := t
   return a


Salu10.

do-while

#15
¡Buenas!

Solo un apunte y no con intencion de faltar a nadie, simplemente con la de informar.

El mcd de dos enteros (d a partir de ahora) a y b, cumple que si c|a y c|b entonces d|c. En estas condiciones se encuentran dos numeros enteros, d y -d.

Para evitar confusiones y por la unicidad de los resultados, se llama mcd(a,b) a max{d,-d}, es decir, al que es positivo.

Otra propiedad del mcd es que mcd(a,b) = mcd (|a|,|b|), por lo que para obtener el mcd de dos enteros por medio del algoritmo de euclides, al trabajar con ordenadores, lo correcto seria trabajar con el valor absoluto de los datos introducidos, ya que de esta forma obtendremos directamente el valor positivo.

Otro apunte es que para calcular el mcd por medio del algoritmo de auclides, se utiliza la division euclidea que dice que dados dos enteros a y b, existen otros dos enteros, unicos, c y r cumpliendo que:

a = cb + r    donde    0 <= r < |b|

Es decir, el resto es positivo, y esto es algo que en C/C++ no se cumple al calcular modulos, ya que si el dividendo y el divisor tienen signos opuestos a%b dara como resultado un entero negativo.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

nicolas_cof

Cita de: do-while... lo correcto seria trabajar con el valor absoluto de los datos introducidos ...

Tenes razon do-while, esto ultimo se me habia pasado por alto! Gracias ;)

Salu10.

do-while

¡De nada!

Todo el mundo tiene algun patinazo de vez en cuando, servidor incluido  :silbar:, faltaria mas.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

cbug

#18
Podría ser esta una solución rápida, me basé en teoremas de congruencias:

#include <stdio.h>

int mcd(int a, int b)
{
 if(b == 0)
   return a;
 else
   mcd(a, a%b);
}

void _abs(int *a)
{
 if(*a < 0) *a *= -1;
}

int main()
{
 int x, y, mxdiv;
 scanf("%d %d", &x, &y);
 _abs(&x);
 _abs(&y);
 printf("\t %d \t %d", x, y);
 mxdiv = mcd(x, y);
 printf("\n MCD > %d \n", mxdiv);
 return 0;
}


Lei que también el operador condicional ? sería un buen reemplazo para ese if de _asb.

nicolas_cof

cbug, fijate en esta parte...

int mcd( int a, int b )
{
  if ( b == 0 )
    return a;
  else
    mcd( b, a % b ); //mcd( a, a % b );
}


Yo usaria la funcion abs() dentro de la funcion mcd(), debido a lo que habia aclarado do-while, que a mi se me habia pasado por alto. Ya que haciendo esto uno se olvida de tener que aplicarle el valor absoluto a los numeros antes de pasarlos a la funcion mcd().

Otro punto que se podria ver, seria usar la funcion abs() de la libreria stdlib.h

#include <stdio.h>
#include <stdlib.h>

int mcd( int a, int b )
{
    a = abs( a );
    b = abs( b );
    return ( b == 0 ) ? a : mcd( b, a % b );
}

int main( void )
{
    int x, y;
    scanf( "%d %d", &x, &y );
    printf( "mcd: %d\n", mcd( x, y ) );
    return 0;
}


Salu10.