Buscar este blog

jueves, 14 de abril de 2016

Numeración Romana con Java

CoAutores: Conrado Rodríguez, Omar Guerra y Alejandro Moreno

Los números enteros en la numeración romana se representa de la siguiente forma:
I V X L C D M
1 5 10 50 100 500 1000

Podemos escribir números romanos mayores de cero y menores de 4000. Pueden repetirse hasta tres veces las cifras (I, X, C, M) ejemplo: el número 30 es XXX, si representamos el 40 su escritura sería XL en vez de XXXX.

En la numeración romana, una cifra menor puede estar a la izquierda del mayor. Ejemplo: el número 150 es CXL = 100 - 10 + 50. En este caso la menor se adiciona al mayor.

A continuación se muestran ejemplos en Java de distintas formas de codificar, de números naturales a romanos y viceversa.

(JAVA) Convertir de números romanos a enteros


    private static int GetNumber(char roman)
    {
        return roman == 'M' ? 1000 :
               roman == 'D' ? 500 :
               roman == 'C' ? 100 :
               roman == 'L' ? 50 :
               roman == 'X' ? 10 :
               roman == 'V' ? 5 :
               roman == 'I' ? 1 : 0;
    } 
Es un método que se utiliza en los siguientes ejemplos:

Ejemplo 1

Un ejemplo muy simple. Se utiliza una iteración.

    public static int Number1(String numberRoman)
    {
        int total = 0, number = 0;
        
        for (int i = 0; i < numberRoman.length(); i++) {
            int numberNow = GetNumber(numberRoman.charAt(i));
            
            if (number == 0){
                number = numberNow; continue;}
            if (number < numberNow)
                number = -number;
            total += number;
            number = numberNow;
        }
        return total + number;
    }
                            

Ejemplo 2

Se utiliza dos iteraciones.

    public static int Number2(String numberRoman)
    {
        int[] array = new int[numberRoman.length()];
        for (int i = 0; i < numberRoman.length(); i++)
        {
            int n1 = GetNumber(numberRoman.charAt(i));
                
            if (i == 0){
                array[i] = n1; continue;
            }
            int n0 = array[i - 1];
            if (n0 < n1)
               array[i - 1] = -n0;
            array[i] = n1;
        }
        int total = 0;
        for(int i : array){ total += i;}
        return total;
    }
                            

Ejemplo 3

        public static int Number3(String numberRoman)
        {
            int number = 0;
            int back = 0;
            for (int j = numberRoman.length() - 1; j >= 0; j--)
            {
                int compare = GetNumber(numberRoman.charAt(j));
                if (compare < back)
                    number -= compare;
                else
                    number += compare;
                back = compare;
            }
            return number;
        } 
 

(JAVA) Convertir de números enteros a romanos 

    private static String getRomans1(int number)
    {
        switch (number)
        {
            case 1: return "I";
            case 2: return "II";
            case 3: return "III";
            case 4: return "IV";
            case 5: return "V";
            case 6: return "VI";
            case 7: return "VII";
            case 8: return "VIII";
            case 9: return "IX";
            case 10: return "X";
            case 20: return "XX";
            case 30: return "XXX";
            case 40: return "XL";
            case 50: return "L";
            case 60: return "LX";
            case 70: return "LXX";
            case 80: return "LXXX";
            case 90: return "XC";
            case 100: return "C";
            case 200: return "CC";
            case 300: return "CCC";
            case 400: return "CD";
            case 500: return "D";
            case 600: return "DC";
            case 700: return "DCC";
            case 800: return "DCCC";
            case 900: return "CM";
            case 1000: return "M";
            case 2000: return "MM";
            case 3000: return "MMM";
            default: return "";
        }
    }
    private static String getRomans2(int number)
    {
        switch (number)
        {
            case 1: return "I";
            case 4: return "IV";
            case 5: return "V";
            case 9: return "IX";
            case 10: return "X";
            case 40: return "XL";
            case 50: return "L";
            case 90: return "XC";
            case 100: return "C";
            case 400: return "CD";
            case 500: return "D";
            case 900: return "CM";
            case 1000: return "M";
            default: return "";
        }
    }
            
Pensaron que sería simple. A continuación se muestran ejemplos que utilizan los métodos anteriores getRomans1 y getRomans2

Ejemplo 1

Un ejemplo muy simple. Se utiliza solo iteraciones.
    public static String Roman6(int natural)
    {
        String numberRoman = "";
        
        //Inicializar un arreglo con los números enteros esenciales para convertir a romano
        int[] numbers = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        
        for (int i = 0; i < numbers.length; i++)
        {
            int number = numbers[i];
            
            //si natural es 2000 y number es 1000
            while (natural >= number)
            {
                //Busca el número romano M y lo concatena a
                //variable numberRoman
                numberRoman += getRomans2(number);
                
                //natural = 2000-1000 = 1000
                natural -= number;
            }
        }
        return numberRoman;
    }
            

Ejemplo 2

Pueden observar que se utiliza las potencias y la recursividad.
    // Se verifica si es un número entero de cuatro, tres, dos o una cifra.
    public static String Roman5(int natural)
    {
        return (natural >= 1000
                ? Roman5(natural, 1000)
                : (natural >= 100
                ? Roman5(natural, 100)
                : (natural >= 10 
                ? Roman5(natural, 10)
                : getRomans1(natural))));
    }
    //Se tranforma a número romano
    private static String Roman5(int natural, int pow)
    {
        // si natural es 150 la variable pow es 100
        // integer = 150/100 = 1
        int integer = natural / pow;
        
        // roman = 1*100 = 100
        int roman = integer * pow;
        // rest = 150 - 100 = 50
        int rest = natural - roman;
        //Recursividad
        // return "C" + Roman5(50)
        return getRomans1(roman) + Roman5(rest);
    }
            

Ejemplo 3

Pueden observar que se utiliza las potencias y una sola iteración.
     public static String Roman4(int natural)
    {
        String numberRoman = "";
        
        //Convertir el número entero a texto
        String textNatural = String.valueOf(natural);
        
        //Recorrer el texto y la variable j sería la potencia.
        // textNatural = 150
        for (int i = 0, j = textNatural.length() - 1; i < textNatural.length(); i++, j--)
        {
            //cuando i=0, num = 1
            int num = Integer.parseInt(String.valueOf(textNatural.charAt(i)));
            
            //cuando i = 0 en este caso j = 2 , potencia = 100
            int potencia = (int)Math.pow(10, j);
            
            // valor = 1*100 = 100
            int valor = num * potencia;
            //adiciona ese valor equivalente a la numeración romana
            //numberRoman = C
            numberRoman += getRomans1(valor);
        }
        
        return numberRoman;
    }
            

Ejemplo 4

Otro ejemplo que se utiliza las potencias y una sola iteración, pero mucho más simple que el ejemplo anterior.
    public static String Roman3(int natural)
    {
        String numberRoman = "";
        
        // una lista de las potencias
        int[] pow = new int[]{1000, 100, 10, 1};
        
        // Recorrer cada una de las potencia
        //natural = 240
        for(int p : pow )
        {
            //Caso que p = 100
            // integer = (140/100)*100 = 200
            int integer = (natural / p) * p;
            
            // natural = 240 - 200 = 40
            natural -= integer;
            //Si integer es menor o igual a cero sigue 
            //con la iteración en caso contrario busca el número romano
            if (integer <= 0) continue;
            numberRoman += getRomans1(integer);
        }
        return numberRoman;
    }
            

Ejemplo 5

Un ejemplo utilizando solo las unidades de medidas. Muy simple para explicarlo.
    public static String Roman2(int natural)
    {
        String[][] list =
        {
            new String[] {"","M","MM","MMM"},
            new String[] {"","C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"},
            new String[] {"","X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"},
            new String[] {"","I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}
        };
        //thousand
        int unitThousand = natural / 1000;
        int unit = natural % 1000;
       //hundred
        int unitHundred = unit / 100;
        unit = unit % 100;
        //dozen
        int unitDozens = unit / 10;
        unit = unit % 10;
        return list[0][unitThousand] + list[1][unitHundred] + list[2][unitDozens] + list[3][unit];
    }
            

Ejemplo 6

Muy simple para explicarlo.
    public static String Roman1(int natural)
    {
        String numberRoman = "";
        
        //thousand
        int unitThousand = natural / 1000;
        int unit = natural % 1000;
        numberRoman += unitThousand == 1 ? "M" :
                 unitThousand == 2 ? "MM" :
                 unitThousand == 3 ? "MMM" : "";
        
        //hundred
        int unitHundred = unit / 100;
        unit = unit % 100;   
        numberRoman += unitHundred == 1 ? "C" : 
                  unitHundred == 2 ? "CC":
                  unitHundred == 3 ? "CCC":
                  unitHundred == 4 ? "CD":
                  unitHundred == 5 ? "D":
                  unitHundred == 6 ? "DC":
                  unitHundred == 7 ? "DCC":
                  unitHundred == 8 ? "DCCC":
                  unitHundred == 9 ? "CM" : "";
        
        //dozen
        int unitDozens = unit / 10;
        unit = unit % 10;
        numberRoman += unitDozens == 1 ? "X" :
                  unitDozens == 2 ? "XX" :
                  unitDozens == 3 ? "XXX" :
                  unitDozens == 4 ? "XL" :
                  unitDozens == 5 ? "L" :
                  unitDozens == 6 ? "LX" :
                  unitDozens == 7 ? "LXX" :
                  unitDozens == 8 ? "LXXX" :
                  unitDozens == 9 ? "XC" : "";
        
        return numberRoman += unit == 1 ? "I" :
                  unit == 2 ? "II" :
                  unit == 3 ? "III" :
                  unit == 4 ? "IV" :
                  unit == 5 ? "V" :
                  unit == 6 ? "VI" :
                  unit == 7 ? "VII" :
                  unit == 8 ? "VIII" :
                  unit == 9 ? "IX" : "";
    }
            

Ejemplo 7

        public static String Roman7(int natural)
        {
            String[] letter = new String[] { "M", "D", "C", "L", "X", "V", "I" };
            int[] value = { 1000, 500, 100, 50, 10, 5, 1, 0 };
            int meter;
            int rest = natural;
            String roman = "";
            for (int i = 0; i < 7; i++)
            {
                if (rest >= value[i])      
                {                       
                    meter = rest / value[i];  
                    if (rest >= value[i + i % 2] * (4 + (4 * (i % 2) + i % 2)))
                    { 
                        roman += letter[i + (i % 2)] + letter[i - 1]; 
                        rest += i % 2 * (value[i + 1] - value[i]);   
                    }
                    else
                        for (int j = 0; j < meter; j++)  
                            roman += letter[i];
                }
                rest %= value[i];
            }
            return roman;
        }
            

Ejemplo 8

        public static String Roman8(int natural)
        {
            String[] romans = new String[] { "I", "V", "X", "L", "C", "D", "M" };
            String romano = String.valueOf(natural);
            String roman = "";
            int s = 4;
            for (int i = 6; i >= 0; i -= 2)
            {
                if (romano.length() == s)
                {
                    char value = romano.charAt(0);
                    int back = i;
                    switch (value)
                    {
                        case '1': { roman += romans[i]; } break;
                        case '2': { roman += romans[i] + romans[i]; } break;
                        case '3': { roman += romans[i] + romans[i] + romans[i]; } break;
                        case '4': { roman += romans[i] + romans[i + 1]; } break;
                        case '5': { roman += romans[i + 1]; } break;
                        case '6': { roman += romans[i + 1] + romans[back]; } break;
                        case '7': { roman += romans[i + 1] + romans[back] + romans[back]; } break;
                        case '8': { roman += romans[i + 1] + romans[back] + romans[back] + romans[back]; } break;
                        case '9': { roman += romans[i] + romans[i + 2]; } break;
                        default: { roman += ""; } break;
                    }
                   
                    romano = romano.substring(1);
                }
                s--;
            }
            return roman;
        } 
Gracias por dedicarle tiempo al artículo. Aceptamos comentarios y críticas.
 
 Que tenga un buen día.
  YAM
 
Dercarga
https://github.com/sitieh2013/numerosromanosjava.git  

No hay comentarios:

Publicar un comentario