martedì 27 settembre 2011

Convertire numeri romani in decimali e viceversa in Java

Mi è capitato di scrivere un programmino per determinare la conversione da numero romano a decimale e viceversa.

Posto il codice sotto, ovviamente non garantisco al 100%, ma sembra funzionare egregiamente.
PS: ho gestito i numeri massimo fino a 3999, infatti non esiste un simbolo romano per il 5000 e 10000 e via dicendo, credo si usino tante M quante sono le migliaia nel numero.

Di seguito posto  il codice usato

package it.test;

public class ConversioneTest {
      static ConversioneTest istanza;
      public static ConversioneTest getInstance(){
            if(istanza==null){
                  istanza=new ConversioneTest();
            }
            return istanza;
      }
    private ConversioneTest(){
     
    }
      /**
       * @param args
       */
      public static void main(String[] args) {
            ConversioneTest t=ConversioneTest.getInstance();
            System.out.println(t.convertToRoman(815));
            System.out.println(t.convertToDecimal("DCCCXV"));

      }
      public int convertToDecimal(String romanNumber){
            int retVal=0;
            char[] listaChar=romanNumber.toCharArray();
            for(int i=0;i<romanNumber.length();i++){
                  if(i!=romanNumber.length()-1){
                        int cifra=getIntFromRomanValue(listaChar[i]);
                        int cifraSuccessiva=getIntFromRomanValue(listaChar[i+1]);
                        if(cifraSuccessiva>cifra){
                             retVal-=cifra;
                        }
                        else
                        {
                             retVal+=cifra;
                        }
                  }
                  else
                  {
                        retVal+=getIntFromRomanValue(listaChar[i]);
                  }
            }
            return retVal;
      }
      public int getIntFromRomanValue(char roman){
            if(roman=='X'){
                  return 10;
            }
            else if(roman=='I'){
                  return 1;
            }
            else if(roman=='V'){
                  return 5;
            }
            else if(roman=='C'){
                  return 100;
            }
            else if(roman=='D'){
                  return 500;
            }
            else if(roman=='M'){
                  return 1000;
            }
            else
            {
                  throw new IllegalArgumentException(String.format("Valore %s inserito " +
                             "non corrisponde ad alcun carattere romano",roman ));
            }
      }
      public  String convertToRoman(int numero){
            StringBuffer sb=new StringBuffer();
            int migliaia=numero/1000;
            int centinaia=(numero-(1000*migliaia))/100;
           
            int decine=(numero-(1000*migliaia)-(100*centinaia))/10;
            int unita=(numero-(1000*migliaia)-(100*centinaia)-(10*decine));
            sb.append(getValoreMigliaia(migliaia));
            sb.append(getValoreCentinaia(centinaia));
            sb.append(getValoreDecina(decine));
            sb.append(getValoreUnita(unita));
            return sb.toString();
      }
      private  String getValoreUnita(int n){
            StringBuffer sb=new StringBuffer();
            switch(n){
            case 0:
                  sb.append("");
                  break;
            case 1:
                  sb.append("I");
                  break;
            case 2:
                  sb.append("II");
                  break;
            case 3:
                  sb.append("III");
                  break;
            case 4:
                  sb.append("IV");
                  break;
            case 5:
                  sb.append("V");
                  break;
            case 6:
                  sb.append("VI");
                  break;
            case 7:
                  sb.append("VII");
                  break;
            case 8:
                  sb.append("VIII");
                  break;
            case 9:
                  sb.append("IX");
                  break;
            }
            return sb.toString();
      }
      private  String getValoreDecina(int n){
            StringBuffer sb=new StringBuffer();
            switch(n){
            case 0:
                  sb.append("");
                  break;
            case 1:
                  sb.append("X");
                  break;
            case 2:
                  sb.append("XX");
                  break;
            case 3:
                  sb.append("XXX");
                  break;
            case 4:
                  sb.append("XL");
                  break;
            case 5:
                  sb.append("L");
                  break;
            case 6:
                  sb.append("LX");
                  break;
            case 7:
                  sb.append("LXX");
                  break;
            case 8:
                  sb.append("LXXX");
                  break;
            case 9:
                  sb.append("XC");
                  break;
            }
            return sb.toString();
      }
      private String getValoreCentinaia(int numero){
            StringBuffer sb=new StringBuffer();
            switch(numero){
            case 0:
                  sb.append("");
                  break;
            case 1:
                  sb.append("C");
                  break;
            case 2:
                  sb.append("CC");
                  break;
            case 3:
                  sb.append("CCC");
                  break;
            case 4:
                  sb.append("CD");
                  break;
            case 5:
                  sb.append("D");
                  break;
            case 6:
                  sb.append("DC");
                  break;
            case 7:
                  sb.append("DCC");
                  break;
            case 8:
                  sb.append("DCCC");
                  break;
            case 9:
                  sb.append("CM");
                  break;
            }
            return sb.toString();
      }
      private String getValoreMigliaia(int numero)
      {
            StringBuffer sb=new StringBuffer();
            switch(numero){
            case 0:
                  sb.append("");
                  break;
            case 1:
                  sb.append("M");
                  break;
            case 2:
                  sb.append("MM");
                  break;
            case 3:
                  sb.append("MMM");
                  break;
                  default:
                        throw new IllegalArgumentException("Massimo numero rappresentabile 3999");
                       
           
            }
            return sb.toString();
      }

}