segunda-feira, 11 de novembro de 2019

Code challenge - Java - Números romanos e swap


#engenhariaDeSoftware #java #codeDuel

Bom dia! Vou apresentar uma das possíveis soluções para o problema de conversão de números romanos em arábicos e vice-versa.





Bom, uma das características da plataforma Java que eu gosto muito é a sua enorme API, especialmente a Collections API, que é fantástica. E isso se aplica muito bem aos algarismos romanos, pois eles são formados por um algarismo e uma dupla:

M: 1000
CM:  1000 - 100 = 900
D: 500
CD: 500 - 100 = 400
C: 100
XC: 100 -10 = 90
L: 50
XL: 50 - 10 = 40
X: 10
IX: 10 - 1 = 9
V: 5
IV: 5 - 1 = 4
I: 1

Podemos pegar o primeiro número menor ou igual ao número arábico, e ir subtraindo e repetindo o loop. Por favor: NÃO USE RECURSAO!

A classe TreeMap tem o método "floorKey()" que faz exatamente isso.

Primeiro, vamos criar 2 mapas:

private final static TreeMap<Integer, String> map = new TreeMap<Integer, String>();
private final static TreeMap<String,Integer> mapReverse = new TreeMap<String,Integer>();

    static String toRoman2(int arabic) {
        TreeMap<Integer,String> map = new TreeMap<Integer,String>();
        map.put(1000,"M");
        map.put(900,"CM");
        map.put(500,"D");
        map.put(400,"CD");
        map.put(100,"C");
        map.put(90,"XC");
        map.put(50,"L");
        map.put(40,"XL");
        map.put(10,"X");
        map.put(9,"IX");
        map.put(5,"V");
        map.put(4,"IV");
        map.put(1,"I");

        StringBuilder result = new StringBuilder();
        int v = map.floorKey(arabic);
        while(v != arabic) {
            result.append(map.get(v));
            arabic -= v;
            v = map.floorKey(arabic);
        }
        result.append(map.get(v));
        return result.toString();
    }

Entendeu? Agora, o contrário: Converter romanos em arábicos: 

    public final static long toArabic(String number) {
    // MCMIV
               TreeMap<String,Integer> mapReverse = new TreeMap<String,Integer>();
               mapReverse.put("M",1000);
        mapReverse.put("CM",900);
        mapReverse.put("D",500);
        mapReverse.put("CD",400);
        mapReverse.put("C",100);
        mapReverse.put("XC",90);
        mapReverse.put("L",50);
        mapReverse.put("XL",40);
        mapReverse.put("X",10);
        mapReverse.put("IX",9);
        mapReverse.put("V",5);
        mapReverse.put("IV",4);
        mapReverse.put("I",1);
    long result = 0;
    for (int i=0; i<number.length(); i++) {
    int alg1 = mapReverse.get(number.charAt(i)+"");
    if(i==number.length()-1) {
    result += alg1;
    }
    else {
    int alg2 = mapReverse.get(number.charAt(i+1)+"");
    if(alg1 >= alg2) {
    result += alg1;
    }
    else {
    result -= alg1;
    }    
    }
    }
    return result;
   
    }

Precisava desse map reverso? Provavelmente não, mas eu quis manter o padrão. 

E sobre o desafio do "swap', ou seja, dados 2 inteiros como intercambiar seus valores sem usar uma terceira variável, é só fazer 3 operações de disjunção exclusiva (XOR): 

public static void main(String[] args) {
int a = 5;
int b = 8;
a = a ^ b;
b = b ^ a;
a = a ^ b; 
System.out.println("a : " + a + " b : " + b);
}


Cleuton Sampaio, M.Sc.






Nenhum comentário:

Postar um comentário