entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Como puedo mejorar este código en Java

Buenas, no estoy seguro de que este sea el lugar mas adecuado para realizar esta pregunta, pero supongo que muchos podréis ayudarme. El caso es que estoy aprendiendo programación Java en el grado superior de DAM y mi práctica final de esta evaluación consiste en hacer un programa que entre otras cosas convierta un nº determinado de euros a billetes y monedas de manera óptima (es decir, que 200 euros no te los haga con 10 billetes de 20).
La práctica la tengo acabada, pero el método que he echo para realizar la conversión de euros me ha quedado muy extenso y no encuentro ninguna manera de acortarlo. Me gustaría saber si me podríais dar algún consejo que me pueda ayudar. Este es el código que se me ocurrió, gracias de antemano:

Introduciendo un double cantidad:

{ 
    int cant, euros;
    System.out.println(cantidad+ " euros son:"); 

    //Transformo los euros a números enteros para que me sea mas fácil trabajar con ellos
    cantidad=cantidad*100;
    euros = (int) cantidad;

    //Uso un if diferente para cada conversión
    if(euros>=50000)
    {
        cant=euros/50000;
        euros=euros%50000;
        System.out.println(cant+ " billete/s de 500€.");
    }
    if(euros>=20000)
    {
        cant=euros/20000;
        euros=euros%20000;
        System.out.println(cant+ " billete/s de 200€.");
    }    
    if(euros>=10000)
    {
        cant=euros/10000;
        euros=euros%10000;
        System.out.println(cant+ " billete/s de 100€.");
    }
    if(euros>=5000)
    {
        cant=euros/5000;
        euros=euros%5000;
        System.out.println(cant+ " billete/s de 50€.");
    }
    if(euros>=2000)
    {
        cant=euros/2000;
        euros=euros%2000;
        System.out.println(cant+ " billete/s de 20€.");
    }
    if(euros>=1000)
    {
        cant=euros/1000;
        euros=euros%1000;
        System.out.println(cant+ " billete/s de 10€.");
    }
    if(euros>=500)
    {
        cant=euros/500;
        euros=euros%500;
        System.out.println(cant+ " billete/s de 5€.");
    }
    if(euros>=200)
    {
        cant=euros/200;
        euros=euros%200;
        System.out.println(cant+ " moneda/s de 2€.");
    }
    if(euros>=100)
    {
        cant=euros/100;
        euros=euros%100;
        System.out.println(cant+ " moneda/s de 1€.");
    }
    if(euros>=50)
    {
        cant=euros/50;
        euros=euros%50;
        System.out.println(cant+ " moneda/s de 50cents.");
    }
    if(euros>=20)
    {
        cant=euros/20;
        euros=euros%20;
        System.out.println(cant+ " moneda/s de 20cents.");
    }
    if(euros>=10)
    {
        cant=euros/10;
        euros=euros%10;
        System.out.println(cant+ " moneda/s de 10cents.");
    }
    if(euros>=5)
    {
        cant=euros/5;
        euros=euros%5;
        System.out.println(cant+ " moneda/s de 5cents.");
    }
    if(euros>=2)
    {
        cant=euros/2;
        euros=euros%2;
        System.out.println(cant+ " moneda/s de 2cents.");
    }
    if(euros>=1)
    {
        cant=euros/1;
        euros=euros%1;
        System.out.println(cant+ " moneda/s de 1cents.");
    }
}

Como veis me ha quedado muy extenso, el caso es que funciona, pero me gustaría mejorarlo.
Un saludo!

1 Respuesta

2votos

Leonardo-Tadei Puntos227020

Hola SensistarX,

el algoritmos que usás está bien planteado.

Podría reducirse bastante con otra sintaxis, que usa el mismo enfoque pero usando una sintaxis un poco diferente y dejando la salida para el final.

Te lo pongo en pseudocódigo, porque hace meses que no toco nada de Java y no ando suelto al escribirlo:

euros = (int) cantidad*100;
a = redondeo(euros/50000);
resto = euros-(50000*a);
b = redondeo(resto/20000);
resto = euros-(20000*b);
c =  redondeo(resto/10000);
resto = euros-(10000*c);
d =  redondeo(resto/5000);
resto = euros-(5000*d);
e =  redondeo(resto/2000);
resto = euros-(2000*e);
f =  redondeo(resto/1000);
resto = euros-(1000*f);
g =  redondeo(resto/500);
resto = euros-(500*g);
h =  redondeo(resto/100);
resto = euros-(100*h);
...
salida("Billetes de 500€ = a);
salida("Billetes de 200€ = b);
salida("Billetes de 100€ = c);
...

A su vez esto podría mejorarse teniendo un vector o lista con las denominaciones y poniendo cada par redondeo/resto en un bucle que itere el vector. Al no tener IF adentro es más simple.

También puede mejorarse que los mensajes de salida sean textos en otro vector, con lo que la salida podría ser otro bucle:

euros = (int) cantidad*100;
monedas = array(50000, 20000, 10000, 5000, ...);
mensajes = array("Billetes de 500€", "Billetes de 200€", "Billetes de 100€",...)
resultado = array(0,0,0,0,...);
para( i=0, i < cantidad(monedas), i++) {
   resultado[i] = redondeo(euros/monedas[i]);
   euros = euros-(monedas[i]*resultado[i]);
}
para( i=0, i < cantidad(mensajes), i++) {
   salida(mensajes[i] + " = " + resultado[i]);
}

También, complicando más la cosa, se podría plantear una función recursiva que vaya procesando cada denominación de billete hasta que no haya más denominaciones, pero no parece que valga la pena.

Otra solución, con un enfoque totalmente distintto sería plantear una jerarquía de clases en que cada moneda sea un objeto de una denominación de moneda, organizadas en árbol (de una sola rama) con cada valor usando elpatrón de diseño Composite, y que el proceso consista en que cada Objeto procese su denominación y le pase al nodo siguiente el resultado para que siga el proceso, hasta que un nodo no tenga más hijos. Es un poco matar moscas a cañonazos, pero sería muy fácil de extender a denominaciones de otros países haciendo que el nodo superior sea la moneda del país a tratar.

Seguro que habrá más soluciones... a veces lo importante es usar la mejor para un caso en particular, teniendo en cuenta la relación costo beneficio de implementarla y la necesidad de posterior reuso.

Saludos cordiales!

0voto

SensistarX comentado

Viendo tu respuesta (por cierto, muy completa, gracias), doy por echo que cuando hablas de vectores es lo que yo conozco como arrays por la nomenclatura que usas en el código. Se me ocurrió intentarlo de esa manera pero no conseguí que funcionase, de todas formas tal y como me lo has puesto lo intentaré de nuevo a ver si consigo que me funcione.
A primera vista supongo que el código me imprimirá todos los billetes y monedas y el número de cada uno, incluyendo los que sean "0", pero trabajaré con ello a ver si puedo hacer una practica en condiciones.
De nuevo gracias por la respuesta.
Un saludo!

Editado: convertido en comentario de la respuesta. No es otra respuesta.

0voto

Leonardo-Tadei comentado

Hola,

efectivamente, los vectores son el nombre castellano de los array. El pseudocódigo que te refiero imprimiría también las denominaciones que sean 0, pero esto es fácil de impedir con un IF, para que solo salgan los mensajes de los elementos que sean diferentes de 0.
La única cuestión con esta solución es tener sincronizados los elementos de cada vector, ya que luego todos los procesos dependen del índice.
Si te falla el código con la solución de lso vectores, consultalo en una neuva pregunta para que podamos verlo: hay en la comunidad varios miembros que manejan muy bien Java.
Saludos!

0voto

SensistarX comentado

EDITO: no me fije pero el código no me tiene en cuenta la parte decimal, trataré de arreglarlo.
EDITO2: ya encontré el fallo, el código funciona.

Efectivamente, con arrays ya he conseguido que me funciones correctamente, y que me muestre solo los billetes/monedas que se necesitan. He echo el código con un ejemplo y le dejaré por aquí:

    double cantidad=333.33;
    cantidad= cantidad*100;
    int euros = (int) cantidad;
    int[] monedas = {50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1};
    String[] mensajes = {"billete/s de 500€","billete/s de 200€","billete/s de 100€","billete/s de 50€","billete/s de 20€","billete/s de 10€","billete/s de 5€","moneda/s de 2€","moneda/s de 1€","moneda/s de 50 cents","moneda/s de 20cents", "moneda/s de 10cents","moneda/s de 5cents","moneda/s de 2 cents","moneda/s de 1cent"};
    int[] resultado = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        for(int i=0; i<15; i++)
        {
            resultado[i] = euros/monedas[i];
            euros=euros-(monedas[i]*resultado[i]);
        }
        System.out.println("\f" +(cantidad/100)+ " euros son:");
        for (int i=0; i<15; i++)
        {
            if(resultado[i]>0)
            {
                System.out.println(resultado[i]+ " " +mensajes[i]);

Muchas gracias por la ayuda.
Un saludo!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta