abc Programski jezik Java
Objektno orijentisano programiranje
22. Pretvaranje iz rimskog u arapski i arapskog u rimski broj.
Opis rješenja:
Napomena citaocu: klasa prezentovana ovde ce da pretvori u arapski broj i"neispravan" rimski broj. Naime, Rimski broj ne smije da sadrzi vise od tri uzastopna
znaka: I, X, C, M, sto znaci da XIIII nije ispravno napisano 14, ispravno bi bilo XIV.
Takodje, prilikom oduzimanja (cifra sa manjom vrijednoscu se nadje prije cifre sa vecom)
Dozvoljene su samo sledece kombinacije: IV - 4, IX - 9, XL - 40, XC - 90, CD - 400, CM - 900.
Tako je recimo IC neispravan rimski broj, a ne 99.
S obzirom da broj pravila i moguce komplikacije prilikom njihovog implementiranja, dati kod
ce pretvarati i neispravne rimske brojeve, a dopuna koda se ostavlja kao vjezba citaocu.
import java.util.*;
/*
* Napomena citaocu: klasa prezentovana ovde ce da pretvori u arapski broj i
* "neispravan" rimski broj. Naime, Rimski broj ne smije da sadrzi vise od tri uzastopna
* znaka: I, X, C, M, sto znaci da XIIII nije ispravno napisano 14, ispravno bi bilo XIV.
*
* Takodje, prilikom oduzimanja (cifra sa manjom vrijednoscu se nadje prije cifre sa vecom)
* Dozvoljene su samo sledece kombinacije: IV - 4, IX - 9, XL - 40, XC - 90, CD - 400, CM - 900.
* Tako je recimo IC neispravan rimski broj, a ne 99.
*
* S obzirom da broj pravila i moguce komplikacije prilikom njihovog implementiranja, dati kod
* ce pretvarati i neispravne rimske brojeve, a dopuna koda se ostavlja kao vjezba citaocu.
*/
class RimskiBroj {
// Cjelobrojna decimalna reprezentacija
private int n;
// Konstruktori
public RimskiBroj(int n) {
/*
* Rimski brojevi ne mogu predstaviti negativne vrijednost te nulu. Za
* predstavljanje brojeva preko 4000 potrebno je koristi dodatne oznake
* koje Java ne podrzava.
*/
if (n < 1)
this.n = 1;
else if (n > 3999)
this.n = 3999;
else
this.n = n;
}
public RimskiBroj(String r) {
/*
* Problem kod pretvaranja Rimskog broja u "normalni", arapski, jeste sto
* X ne mora uvijek predstavljati broj 10. Naime ako se X nadje ispred C, tada kombinacija XC postaje 90,
* sto znaci da ne mozemo na osnovu samo jednog slova odrediti njegovu vrijednost.
*/
r = r.toUpperCase(); // Pretvori sva slova u velika da ne binemo o tome.
this.n = 0; // Na pocetku je nula, kako saznajemo cifre, povecavacemo ovu vrijednost.
for(int i = 0; i < r.length(); ++i)
{
int prvaCifra = vrijednostRimskeCifra(r.charAt(i));
int drugaCifra;
/* Ako provjeravamo zadnju cifru, ocigledno ne postoji sledeca, tako da stavimo njenu
vrijednost na nulu tako da ne prodje donji uslov */
if(i == r.length() - 1)
drugaCifra = 0;
else
drugaCifra = vrijednostRimskeCifra(r.charAt(i + 1));
/* Vrijednost ce se oduzimati samo ako je vrijednost prve manja od vrijednosti druge */
if(prvaCifra < drugaCifra)
n += drugaCifra - prvaCifra;
else
n += prvaCifra; // Drugu ostavljamo, jer ce ona biti prvaCifra u drugom krugu.
}
}
private int vrijednostRimskeCifra(char cifra)
{
int vrijednost = 0;
switch (cifra)
{
case 'I':
vrijednost = 1;
break;
case 'V':
vrijednost = 5;
break;
case 'X':
vrijednost = 10;
break;
case 'L':
vrijednost = 50;
break;
case 'C':
vrijednost = 100;
break;
case 'D':
vrijednost = 500;
break;
case 'M':
vrijednost = 1000;
break;
default:
vrijednost = -1;
}
return vrijednost;
}
// Pretvaranje rimskog u decimalni broj
public int toInt() {
return n;
}
// Pretvaranje decimalnog u rimski broj
public String toString() {
return arapskiURimski(n);
}
// Pomocni rekurzivni metod za pretvaranje
// decimalnog broja u rimski broj
private String arapskiURimski(int n) {
if (n >= 1000) return "M" + arapskiURimski(n - 1000);
if (n >= 900) return "CM" + arapskiURimski(n - 900);
if (n >= 500) return "D" + arapskiURimski(n - 500);
if (n >= 400) return "CD" + arapskiURimski(n - 400);
if (n >= 100) return "C" + arapskiURimski(n - 100);
if (n >= 90) return "XC" + arapskiURimski(n - 90);
if (n >= 50) return "L" + arapskiURimski(n - 50);
if (n >= 40) return "XL" + arapskiURimski(n - 40);
if (n >= 10) return "X" + arapskiURimski(n - 10);
if (n >= 9) return "IX" + arapskiURimski(n - 9);
if (n >= 5) return "V" + arapskiURimski(n - 5);
if (n >= 4) return "IV" + arapskiURimski(n - 4);
if (n >= 1) return "I" + arapskiURimski(n - 1);
return "";
}
// Staticki metod za sabiranje dva rimska broja:
// RimskiBroj z = RimskiBroj.zbir(x, y)
public static RimskiBroj zbir(RimskiBroj a, RimskiBroj b) {
return new RimskiBroj(a.n + b.n);
}
// Objektni metod za sabiranje dva rimska broja:
// RimskiBroj z = x.dodaj(y);
public RimskiBroj dodaj(RimskiBroj a) {
return new RimskiBroj(this.n + a.n);
}
// Staticki metod za proizvod dva rimska broja:
// RimskiBroj z = RimskiBroj.proizvod(x, y)
public static RimskiBroj proizvod(RimskiBroj a, RimskiBroj b) {
return new RimskiBroj(a.n * b.n);
}
// Objektni metod za proizvod dva rimska broja:
// RimskiBroj z = x.pomnoži(y);
public RimskiBroj pomnoži(RimskiBroj a) {
return new RimskiBroj(this.n * a.n);
}
public static void main(String[] args) {
RimskiBroj x = new RimskiBroj("xxxiiii"); // 34
System.out.println("x = " + x.toInt());
System.out.println("x = " + x); // x.toString()
RimskiBroj y = new RimskiBroj("mdclxvi"); // 1666
System.out.println("y = " + y.toInt());
System.out.println("y = " + y); // y.toString()
System.out.println();
// RimskiBroj.zbir(x,y).toString()
System.out.println("x+y = " + RimskiBroj.zbir(x, y));
System.out.println("x+y = " + RimskiBroj.zbir(x, y).toInt());
// x.dodaj(y).toString()
System.out.println("x+y = " + x.dodaj(y));
System.out.println("x+y = " + x.dodaj(y).toInt());
System.out.println();
// RimskiBroj.proizvod(x,y).toString()
System.out.println("x*y = " + RimskiBroj.proizvod(x, y));
System.out.println("x*y = " + RimskiBroj.proizvod(x, y).toInt());
// x.pomnoži(y).toString()
System.out.println("x*y = " + x.pomnoži(y));
System.out.println("x*y = " + x.pomnoži(y).toInt());
}
}
Ispis na ekranu:
Index
|
|