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 +++++++++++++++++++++++++++
contoh hasilnya :
mmmcdxlix
3449
BUILD SUCCESSFUL (total time: 0 seconds)
mcmxcix
1999
BUILD SUCCESSFUL (total time: 0 seconds)
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)