Pages

Minggu, 31 Maret 2013

Angka Romawi

kemarin pernah ada temen yang nanya-nanya tentang gimana cara mengkonversi angka romawi ke dalam angka arab (angka latin) yang biasa kita gunakan. sebetulnya teorinya mudah, cuman ternyata menerapkannya susah juga :D
aturan penulisan romawi pada dasarnya seperti ini :
1. tidak mungkin lebih dari 4 angka sama yang berjajar, maksimal 3 seperti iii, xxx, mmm
2. memiliki urutan sebagai berikut i,v,x,l,c,d,m
3. terdapat aturan pengurangan hanya dengan angka dengan urutan +1 dan +2, misal i dan v, jika digabung iv hasilnya 5-1=4, begitu juga dengan ix, tetapi tidak ada il, ic dst
4. aturan diatas tidak berlaku untuk angka yang bila dikonversi, memiliki kepala 5, misal v=5, l=50 dan d=500, mungkin emang krn menunjukkan nilai 1/2 (nebak aja :D)
5. 1990=mcmxc dan bukan mdcdxc yang berarti prioritas penulisan adalah nilai 5+3 dan bukan 5+4, mudahnya jika kita ingin menuliskan 19 maka bukan dengan 10+5+4 tetapi 10+10-1, tetapi jika kita ingin menuliskan 18 maka 10+5+3. (maaf gak tau cara njelasinnya, pokoke gitu deh :D)

kodingan java ini masih memiliki kekurangan yaitu belum memiliki method validasi apakah penulisannya benar, jadi tidak bisa mendeteksi xix dengan xviv yang sama-sama 19.
sudah aku coba beberapa nilai romawi dan udah benar, gak tau ntar teman2 menemukan bug hasil yang tidak sesuai :D

oke ini kodingan javanya +++++++++++++++++++++++++++

public class Romawi {  
    String [] order = {"I","V","X","L","C","D","M"};
    String [] rom;
    int [] nilai; //attribut ini tidak dipakai
    int sum = 0;
    public Romawi(){
        nilai = new int[7];
        for(int i=0; i<7;i++){
            nilai[i]=0;
        }
    }
    public int romawiValue(String x){
        int len = x.length();
        if(len==1){
            return getValue(x);
        }else{
            return getValue(x,len);
        }
        //return 0;
    }
    /*
     * mendapatka nilai satu digit
     */
    private int getValue(String rom){
        String x = rom.toUpperCase();
        if(x.equalsIgnoreCase("I")){
            return 1;
        }else if(x.equalsIgnoreCase("V")){
            return 5;
        }else if(x.equalsIgnoreCase("X")){
            return 10;
        }else if(x.equalsIgnoreCase("L")){
            return 50;
        }else if(x.equalsIgnoreCase("C")){
            return 100;
        }else if(x.equalsIgnoreCase("D")){
            return 500;
        }else if(x.equalsIgnoreCase("M")){
            return 1000;
        }
        return 0;
    }
    /*
     * mendapatkan nilai > 1 digit
     */
    private int getValue(String rom, int length){
        if(length==2){
            if(cekOrder(rom)){
                return getValue(rom.substring(1, 2))-getValue(rom.substring(0, 1));
            }else{
               return getValue(rom.substring(1, 2))+getValue(rom.substring(0, 1));
            }
        }else{
            if(this.romValidate(rom)){
                return this.sum;
            }
        }
        return 0;
    }
    /*
     * hanya berlaku untuk 2 digit angka romawi
     */
    private boolean cekOrder(String rom){
        int len = this.order.length;
        for(int i=0; i<len-2; i++){
            if(rom.substring(0, 1).equalsIgnoreCase(this.order[i]) && rom.substring(1, 2).equalsIgnoreCase(this.order[i+1])){               
                return true;              
            }else if(rom.substring(0, 1).equalsIgnoreCase(this.order[i]) && rom.substring(1, 2).equalsIgnoreCase(this.order[i+2])){
                return true;
            }
        }
        return false;
    }
    private boolean cekOrder(int start){
        int len = this.order.length;           
        for(int i=0; i<len-2; i++){
            if(start<this.rom.length-2){               
                    if(this.rom[start].equalsIgnoreCase(this.order[i]) && this.rom[start+1].equalsIgnoreCase(this.order[i+1])){                       
                        return true;            
                    }else if(this.rom[start].equalsIgnoreCase(this.order[i]) && this.rom[start+1].equalsIgnoreCase(this.order[i+2])){                       
                        return true;
                    }
            }else if(start==this.rom.length-2){
                    if(this.rom[start].equalsIgnoreCase(this.order[i]) && this.rom[start+1].equalsIgnoreCase(this.order[i+1])){                       
                        return true;            
                    }else if(this.rom[start].equalsIgnoreCase(this.order[i]) && this.rom[start+1].equalsIgnoreCase(this.order[i+2])){                       
                        return true;
                    }
            }
        }
        return false;
    }
    private void splitToArray(String rom){
        char[] romchar = rom.toCharArray();
        int jml = romchar.length;
        this.rom = new String[jml];
        for(int i=0;i<jml;i++){
            this.rom[i] = ""+romchar[i];           
        }
    }
    /*
     * 1.validasi apakah huruf romawi benar huruf2nya
     * 2.validasi apakah huruf romawi benar urutannya.
     */
    public boolean romValidate(String rom){
        //pecah dulu menjadi array, biar mudah ngolahnya
        this.splitToArray(rom);
        int jml = this.rom.length;      
        //cek apakah huruf romawi benar per hurufnya
        for(int i=0;i<jml;i++){
            for(int j=0;j<this.order.length;j++){
                if(this.rom[i].equalsIgnoreCase(this.order[j].trim())) {
                    break;
                }
                if(j==this.order.length-1 && !this.rom[i].equalsIgnoreCase(this.order[j].trim())){
                    return false;
                }
            }
        }
        int len = this.order.length;      
        this.sumRom(this.rom, 0, jml);  
        return true;
    }
    public void sumRom(String[] rom, int start, int len){       
        if(start < len-2){          
            if(rom[start].equalsIgnoreCase(rom[start+1]) && rom[start+1].equalsIgnoreCase(rom[start+2])){               
                this.sum += (this.getValue(rom[start])+this.getValue(rom[start+1])+this.getValue(rom[start+2]));
                this.sumRom(rom, start+3, len);             
            }else if(rom[start].equalsIgnoreCase(rom[start+1]) && !rom[start+1].equalsIgnoreCase(rom[start+2])){             
                this.sum += (this.getValue(rom[start])+this.getValue(rom[start+1]));
                this.sumRom(rom, start+2, len);             
            }else if(!rom[start].equalsIgnoreCase(rom[start+1])){
                if(this.cekOrder(start)){                  
                    this.sum += (this.getValue(rom[start+1])-this.getValue(rom[start]));
                    this.sumRom(rom, start+2, len);                 
                }else{                 
                    this.sum += this.getValue(rom[start]);                  
                    this.sumRom(rom, start+1, len);
                }
            }
        }else if(start == len-2){
            if(this.cekOrder(start)){                  
                    this.sum += (this.getValue(rom[start+1])-this.getValue(rom[start]));                   
                }else{                  
                    this.sum += this.getValue(rom[start])+ this.getValue(rom[start+1]);                   
            }
        }
    }
    public static void main(String[] args) {
        // TODO code application logic here      
        Romawi rom = new Romawi();
        String x = "mmmcdxlix";
        System.out.println(x);
        System.out.println(rom.romawiValue(x));       
    }
}

contoh hasilnya :
mmmcdxlix
3449
BUILD SUCCESSFUL (total time: 0 seconds)

mcmxcix
1999
BUILD SUCCESSFUL (total time: 0 seconds)

0 komentar:

Posting Komentar