Chi è in grado di darmi qualche dritta su come posso realizzare una classe la quale mi permetta di trasformare numeri arabi in romani e viceversa?
Oppure dove posso trovare un sito che mi possa aiutare?
Chi è in grado di darmi qualche dritta su come posso realizzare una classe la quale mi permetta di trasformare numeri arabi in romani e viceversa?
Oppure dove posso trovare un sito che mi possa aiutare?
Giuseppe SPECCHIO
gia che ci sei anche a me serviva una cosa del genere...
![]()
ma non date risposte del genere fate perdere solo del tempo![]()
Giuseppe SPECCHIO
prova a vedere questo:
http://www.programmersheaven.com/zone3/cat414/22243.htm
Finalmente consultando la rete sono riuscito a trovare un'algoritmo che mi permetta di definire la classe che trasforma un numero arabo (1...3999) in romano, seguendo le suddette specifiche:
In teoria non sarebbe possibile, anche se la materia è controversa.
Ecco le regole per la numerazione romana:
I: 1
II: 2
III: 3
IV /IIII: 4
V: 5
X: 10
L: 50
C: 100
D: 500
M: 1000
la scrittura del numero 4 era originariamente IV, ma in qualche caso è stato utilizzato il simbolo IIII. Un’eccezione costante alla regola originaria la fanno i quadranti degli orologi di prestigio, tutti col IIII.
La regola prevede che si possa anteporre il simbolo precedente al solo simbolo successivo nella scala dei simboli per sottrarre a questi il proprio valore, purché il simbolo precedente sia di un solo carattere e non sia multiplo di 5.
Ovvero si può scrivere XL per 40, CD per 400, XC per 90, ma non VX per 5 o LD per 450. Unica eccezione alla regola è il numero 4 che, scritto come IV, va considerato come un simbolo unico.
Allo stesso modo, non si potrebbe scrivere IM per 999 perché sottrarrebbe I da M, rispettivamente il primo e l’ultimo elemento della scala di valori.
Alcuni esempi:
1492: MCDXCII
1991: MCMXCI
40: XL
49: XLIX (ma potremmo scrivere IL, forzando la regola)
Da tali premesse ho implementato Romani.java:
/** classe che gestisce i numeri romani */
public class Romani {
/************************************************ le variabili di istanza **********************************************/
private String NrRomano="";
int NrArabo;
/************************************************** *** i costruttori ************************************************** */
/** costruisce un oggetto di tipo Romani String Nr.Romano
@param s di tipo Individuo, dati anagrafici dello studente corrispondente
all’oggetto Romani che si sta costruendo
@param n di tipo int, è il numero arabo da convertire
*/
public Romani(int n) {
if((n>0)&&(n<4000))
NrArabo = n;
else
//condizione di errore
NrRomano = "";
}//Romani
/************************************************** *** i metodi di accesso *********************************************/
/** @return il riferimento ad un oggetto di tipo String che corrisponde
al numero romano il quale rappresentata dall’oggetto ricevente */
public String getNumeroRomano() {
return NrRomano;
}//getNumeroRomano
/************************************************** ******** il metodo di utilita’ **************************************/
/** @return il riferimento ad un oggetto di tipo String che rappresenta
lo studente corrispondente all’oggetto ricevente */
public String toString() {
return NrArabo+" = "+NrRomano;
}//toString
/************************************************** ******* i metodi relazionali ****************************************/
/**@return il numero romano dell’oggetto ricevente*/
public String calcolaNumeroRomano(){
int[] VettArabo;
int count=0; //determina la lunghezza del vettore
int quoziente,i; //buffer
/*dividere il numero arabo per 10, conteggiando il numero di divisioni, fino a quando il quoziente non è pari
a zero, in modo tale da ricavare l'ordne del vettore e scindere il numero in cifre*/
quoziente=NrArabo;
do{
quoziente=quoziente/10;
count++;
}while(quoziente!=0);
//instanzio il vettore
VettArabo = new int[count];
//divido il numero in cifre mettendo alla cifra più significativa le migliaia e in quella meno significativa le unità
for(i=VettArabo.length;i<=0;i--){ //NON ENTRA NEL CICLO !!
VettArabo[i] = NrArabo%10;
System.out.print("VettArabo["+i+"]"+VettArabo[i]);
NrArabo/=10;
}//for
//Conversione
for(i=0;i<VettArabo.length;i++){
if(count==4){ //migliaia
if(VettArabo[i]==1)
NrRomano=NrRomano+"M";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"MM";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"MMM";
}//if count=4
else if (count==3){ //centinaia
if(VettArabo[i]==1)
NrRomano=NrRomano+"C";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"CC";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"CCC";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"CD";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"D";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"DC";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"DCC";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"DCCC";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"CM";
}//if count=3
else if (count==2){ //decine
if(VettArabo[i]==1)
NrRomano=NrRomano+"X";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"XX";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"XXX";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"XL";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"L";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"LX";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"LXX";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"LXXX";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"XC";
}//if count=2
else if (count==1){ //unità
if(VettArabo[i]==1)
NrRomano=NrRomano+"I";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"II";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"III";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"IV";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"V";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"VI";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"VII";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"VIII";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"IX";
}//if count=1
count--;
}//for
return NrRomano;
}//calcolaNumeroRomano
}//Romani
e la rispettiva classe di test definita TestRomani.java:
public class TestRomani {
/* classe di test per la classe Studente */
public static void main (String[] args) {
Romani NR; // numero romano
String risposta = "s",tmp; // per leggere le risposte dell’utente
int n;//numero arabo da convertire
int i; //index
/* visualizzazione della finalita’ della classe */
System.out.println("Classe di test per la classe Numeri Romani");
System.out.println();
/* ciclo di test */
while (risposta.equals("s")) {
System.out.print("Numero Arabo: ");
n = Input.readInt();
NR = new Romani(n);
tmp = NR.calcolaNumeroRomano();
if(tmp=="")
System.out.println("Errore nell'inserimento dei dati.");
else
System.out.println(n+" = "+tmp);
/* nuova interrogazione dell’utente e lettura della sua risposta */
System.out.print("Vuoi Inserire un nuovo Numero? [s/n] ");
risposta = Input.readString();
System.out.println();
}//while
}//main
}//TestRomani{}
Dalla compilazione non risultano errori sintattici, ma da un'attenta analisi step by step ho notato che probabilmente c'è un'errore semantico nel seguente ciclo contenuto nel file Romani.java:
...
//divido il numero in cifre mettendo alla cifra più significativa le migliaia e in quella meno significativa le unità
for(i=VettArabo.length;i<=0;i--){ //NON ENTRA NEL CICLO !!
VettArabo[i] = NrArabo%10;
System.out.print("VettArabo["+i+"]"+VettArabo[i]);
NrArabo/=10;
}//for
...
Si capisce facilmente dal commento questo ciclo for con down to cosa dovrebbe fare! Il condizionale è dobbligo inquanto stranamente non ci si entra mai nel ciclo!!
Se qualcuno è in grado di darmi qualche giustificazione ne sarei grato.
Giuseppe SPECCHIO
L'errore e' nell'inizializzazione del ciclo for: inizializzi una variabile pari alla lunghezza dell'array, e poi dici di ciclare se quella variabile e' minore di zero, cioe' mai.for(i=VettArabo.length;i<=0;i--){ //NON ENTRA NEL CICLO !!
VettArabo[i] = NrArabo%10;
System.out.print("VettArabo["+i+"]"+VettArabo[i]);
NrArabo/=10;
}//for
...
Si capisce facilmente dal commento questo ciclo for con down to cosa dovrebbe fare! Il condizionale è dobbligo inquanto stranamente non ci si entra mai nel ciclo!!
Se qualcuno è in grado di darmi qualche giustificazione ne sarei grato.
Qui gli errori sono due:
il primo sta nella condizione di confronto, non devi mettere i <= 0, ma il contrario, i >= 0;
il secondo, piu' sottile, sta nell' inizializzazione della variabile di controllo:
se metti i = Vett.length ti dara' un' eccezione di tipo ArrayIndexOutOfBound ( o qualcosa del genere, non ricordo la sintassi), devi inizializzarla al valore Vett.length - 1
Ciao,
Lorenzo
Ho cercato d'implementare ora un metodo che fa l'operazione opposta, cioè conversione da numero romano ad arabo, va quasi tutto bene inquanto la conversione va a buon fine fino al penultimo carattere il quale non viene letto per una questione d'indici, ottenendo così una conversione non veritiera. Cioè quando verifico la condizione
...
//Conversione
while(i<NrRomano.length()){ //NrRomano contiene il valore da convertire in arabo
if(NrRomano.substring(i,i+1).equals("M")) //migliaia
...
ottengo il seguente errore:
C:\j2sdk1.4.1_01\bin>java TestRomani
Classe di test per la classe Numeri Romani
Numero Arabo: 23
23 = XXIII
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String ind
ex out of range: 6
at java.lang.String.substring(String.java:1477)
at Romani.calcolaNumeroArabo(Romani.java:209)
at TestRomani.main(TestRomani.java:30)
però se limito di un carattere la lunghezza della stringa che rappresenta il numero romano non ho una conversione esatta, come riportato nell'esempio sottostante:
C:\j2sdk1.4.1_01\bin>java TestRomani
Classe di test per la classe Numeri Romani
Numero Arabo: 23
23 = XXIII
XXIII = 22
Vuoi Inserire un nuovo Numero? [s/n] s
Numero Arabo: 45
45 = XLV
XLV = 40
Vuoi Inserire un nuovo Numero? [s/n] n
come si vede il non considerare l'ultimo carattere sballa totalmente il risultato.
Per completezza vi riporto il listato del metodo e la classe di test:
/*@return il numero arabo dell’oggetto ricevente*/
public int calcolaNumeroArabo(){
int i=0;
//Conversione
while(i<NrRomano.length()-1){ //ERRORRE: non legge l'ultimo carattere
if(NrRomano.substring(i,i+1).equals("M")) //migliaia
NrArabo+=1000;
else if (NrRomano.substring(i,i+1).equals("C")) //centinaia
if(NrRomano.substring(i,i+2).equals("CD")){ //400
NrArabo+=400;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("CM")){ //900
NrArabo+=900;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=100;
else if (NrRomano.substring(i,i+1).equals("D"))
NrArabo+=500;
else if (NrRomano.substring(i,i+1).equals("X")) //decine
if(NrRomano.substring(i,i+2).equals("XL")){ //40
NrArabo+=40;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("XC")){ //90
NrArabo+=90;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=10;
else if (NrRomano.substring(i,i+1).equals("L"))
NrArabo+=50;
else if (NrRomano.substring(i,i+1).equals("I")) //unità
if(NrRomano.substring(i,i+2).equals("IV")){ //4
NrArabo+=4;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("IX")){ //9
NrArabo+=9;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=1;
else if (NrRomano.substring(i,i+1).equals("V"))
NrArabo+=5;
i++; //incrementa posizione successiva
}//while
return NrArabo;
}//calcolaNumeroArabo
Classe si test:
public class TestRomani {
/* classe di test per la classe Studente */
public static void main (String[] args) {
Romani NR; // numero romano
String risposta = "s",tmp; // per leggere le risposte dell’utente
int n;//numero arabo da convertire
/* visualizzazione della finalita’ della classe */
System.out.println("Classe di test per la classe Numeri Romani");
System.out.println();
/* ciclo di test */
while (risposta.equals("s")) {
//conversione da arabo a romano
System.out.print("Numero Arabo: ");
n = Input.readInt();
NR = new Romani(n);
tmp = NR.calcolaNumeroRomano();
if(tmp=="")
System.out.println("Errore nell'inserimento dei dati.");
else
System.out.println(n+" = "+tmp);
//conversione da romano ad arabo
NR = new Romani(tmp);
n = NR.calcolaNumeroArabo();
if(n==-1)
System.out.println("Errore nell'inserimento dei dati.");
else
System.out.println(tmp+" = "+n);
/* nuova interrogazione dell’utente e lettura della sua risposta */
System.out.print("Vuoi Inserire un nuovo Numero? [s/n] ");
risposta = Input.readString();
System.out.println();
}//while
}//main
}//TestRomani
Se siente in gardo di risolvere questo problema x favore aiutatemi!!!
Giuseppe SPECCHIO
/* classe che gestisce i numeri romani */
public class Romani {
private String NrRomano="";
private int NrArabo;
private boolean error=false;
/* costruisce un oggetto di tipo Romani String Nr.Romano
@param s di tipo Individuo, dati anagrafici dello studente corrispondente
all’oggetto Romani che si sta costruendo
@param n di tipo int, è il numero arabo da convertire
*/
public Romani(int n) {
if((n>0)&&(n<4000))
NrArabo = n;
else{
//condizione di errore
NrRomano = "";
error=true;
}
}//Romani
public Romani(String s) {
if(s.length()!=0) NrRomano=s;
else {
NrArabo=0;
error=true;
}
}
/** @return il riferimento ad un oggetto di tipo String che corrisponde
al numero romano il quale rappresentata dall’oggetto ricevente */
public String getNumeroRomano() {
return NrRomano;
}//getNumeroRomano
/** @return il riferimento ad un oggetto di tipo String che rappresenta
lo studente corrispondente all’oggetto ricevente */
public String toString() {
return NrArabo+" = "+NrRomano;
}//toString
/**@return il numero romano dell’oggetto ricevente*/
public String calcolaNumeroRomano(){
//Volendo "gestire" l'errore
i(error) return "";
int[] VettArabo;
int count=0; //determina la lunghezza del vettore
int quoziente,i; //buffer
/*dividere il numero arabo per 10, conteggiando il numero di divisioni, fino a quando il quoziente non è pari
a zero, in modo tale da ricavare l'ordne del vettore e scindere il numero in cifre*/
quoziente=NrArabo;
do{
quoziente=quoziente/10;
count++;
}while(quoziente!=0);
//instanzio il vettore
VettArabo = new int[count];
//divido il numero in cifre mettendo alla cifra più significativa le migliaia e in quella meno significativa le unità
for(i=VettArabo.length-1;i>=0;i--){ //NON ENTRA NEL CICLO !!
VettArabo[i] = NrArabo%10;
System.out.print("VettArabo["+i+"]"+VettArabo[i]);
NrArabo/=10;
}//for
//Conversione
for(i=0;i<VettArabo.length;i++){
if(count==4){ //migliaia
if(VettArabo[i]==1)
NrRomano=NrRomano+"M";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"MM";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"MMM";
}//if count=4
else if (count==3){ //centinaia
if(VettArabo[i]==1)
NrRomano=NrRomano+"C";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"CC";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"CCC";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"CD";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"D";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"DC";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"DCC";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"DCCC";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"CM";
}//if count=3
else if (count==2){ //decine
if(VettArabo[i]==1)
NrRomano=NrRomano+"X";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"XX";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"XXX";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"XL";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"L";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"LX";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"LXX";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"LXXX";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"XC";
}//if count=2
else if (count==1){ //unità
if(VettArabo[i]==1)
NrRomano=NrRomano+"I";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"II";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"III";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"IV";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"V";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"VI";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"VII";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"VIII";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"IX";
}//if count=1
count--;
}//for
return NrRomano;
}//calcolaNumeroRomano
/*@return il numero arabo dell’oggetto ricevente*/
public int calcolaNumeroArabo(){
//Anche qui volendo "gestire" l'errore
if(error) return -1;
int i=0;
//Conversione
while(i<NrRomano.length()-1){ //ERRORE: non legge l'ultimo carattere
if(NrRomano.substring(i,i+1).equals("M")) //migliaia
NrArabo+=1000;
else if (NrRomano.substring(i,i+1).equals("C")) //centinaia
if(NrRomano.substring(i,i+2).equals("CD")){ //400
NrArabo+=400;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("CM")){ //900
NrArabo+=900;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=100;
else if (NrRomano.substring(i,i+1).equals("D"))
NrArabo+=500;
else if (NrRomano.substring(i,i+1).equals("X")) //decine
if(NrRomano.substring(i,i+2).equals("XL")){ //40
NrArabo+=40;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("XC")){ //90
NrArabo+=90;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=10;
if (NrRomano.substring(i,i+1).equals("L"))
NrArabo+=50;
if (NrRomano.substring(i,i+1).equals("I")){ //unità
if(NrRomano.substring(i,i+2).equals("IV")){ //4
NrArabo+=4;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("IX")){ //9
NrArabo+=9;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=1;
}
else if (NrRomano.substring(i,i+1).equals("V"))
NrArabo+=5;
i++; //incrementa posizione successiva
}//while
//Qui si controlla l'ultimo carattere fuori dal while.
//Non controlliamo i caratteri doppi in quanto non ce ne possono
//essere
if(NrRomano.charAt(i)==('M')) //migliaia
NrArabo+=1000;
else if (NrRomano.charAt(i)==('C')) //centinaia
NrArabo+=100;
else if (NrRomano.charAt(i)==('D'))
NrArabo+=500;
else if (NrRomano.charAt(i)==('X')) //decine
NrArabo+=10;
if (NrRomano.charAt(i)==('L'))
NrArabo+=50;
if (NrRomano.charAt(i)==('I')) //unità
NrArabo+=1;
else if (NrRomano.charAt(i)==('V'))
NrArabo+=5;
return NrArabo;
}//calcolaNumeroArabo
}//Romani
Una soluzione veloce potrebbe essere quella di controllare alla fine del while l'ultimo carattere . Come facevi andava bene per tutti i caratteri tranne l'ultimo. Es.
0 1 2 3
"X X I I"
Len= 4;
quando la i si trova nella posizione 3 non entra nel ciclo while,
while(i<NrRomano.length()-1), ed è giusto così.
Se provi a farlo entrare, imponendo la condizione
while(i<NrRomano.length()) ti da StringIndexOutOfBoundException,
perchè vai a fare la substring(i,i+1); cioè di (3,4), dove il valore 4 del puntatore non è un valore valido.
Questa non è l'unica soluzione. Ce ne sono tante altre
Ho aggiunto un valore Booleano per controllare se c'è stato un errore di immissione ed evitare così di far si che compaia la scritta StringIndexOutofBoundsException
:metallica :metallica
Ti ringrazio per il suggerimento ma io peeferisco non usare la variabile booleana come flag di errore ma preferisco andare a testare semplicemente il valore della variabile NrArabo e NrRomano, anche se la tua soluzione è corretta, ripeto di ringrazio ancora comunque!! Ne approfitto ancora anche perchè è sorto un altro piccolo problema, cioè la routine che converte da numero romano ad arabo funziona quasi correttamente inquanto quando devo convertire un nuemro romano composto da 2 cifre ad esempio 4=IV , 9=IX etc. ho sempre il fatitico errore come riportato nell'esempio sottostante:
Numero Arabo: 4
4 = IV
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String ind
ex out of range: 2
at java.lang.String.charAt(String.java:460)
at Romani.calcolaNumeroArabo(Romani.java:228)
at TestRomani.main(TestRomani.java:30)
C:\j2sdk1.4.1_01\bin>java TestRomani
Classe di test per la classe Numeri Romani
Numero Arabo: 3999
3999 = MMMCMXCIX
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String ind
ex out of range: 9
at java.lang.String.charAt(String.java:460)
at Romani.calcolaNumeroArabo(Romani.java:228)
at TestRomani.main(TestRomani.java:30)
In seguito ti riporto il listato della classe romani:
/** classe che gestisce i numeri romani */
public class Romani {
/************************************************ le variabili di istanza **********************************************/
private String NrRomano="";
private int NrArabo;
/************************************************** *** i costruttori ************************************************** */
/** costruisce un oggetto di tipo Romani String Nr.Romano
@param n di tipo int, è il numero arabo da convertire
*/
public Romani(int n) {
if((n>0)&&(n<4000))
NrArabo = n;
else
//condizione di errore
NrRomano = "";
}//Romani
/** costruisce un oggetto di tipo Romani String Nr.Romano
@param s di tipo String, è il numero romano da convertire
*/
public Romani(String s) {
if(isRomano(s)) //se il numero romano è stato scritto correttamente
NrRomano=s;
else
//condizione di errore
NrArabo=-1;
}//Romani
/************************************************** *** i metodi di accesso *********************************************/
/** @return il riferimento ad un oggetto di tipo String che corrisponde
al numero romano il quale rappresentata dall’oggetto ricevente */
public String getNumeroRomano() {
return NrRomano;
}//getNumeroRomano
/** @return il riferimento ad un oggetto di tipo int che corrisponde
al numero arabo il quale rappresentata dall’oggetto ricevente */
public int getNumeroArabo() {
return NrArabo;
}//getNumeroArabo
/************************************************** ******** il metodo di utilita’ **************************************/
/** @return il riferimento ad un oggetto di tipo String che rappresenta
lo studente corrispondente all’oggetto ricevente */
public String toString() {
return NrArabo+" = "+NrRomano;
}//toString
/************************************************** ******* i metodi relazionali ****************************************/
/**@return il numero romano dell’oggetto ricevente
@error restituisce una stringa vuota laddove si è configurato un errore nell'inserimento dei dati
*/
public String calcolaNumeroRomano(){
int[] VettArabo; //identifica il numero arabo scomposto in cifre
int count=0; //determina la lunghezza del vettore
int quoziente,i; //buffer
/*dividere il numero arabo per 10, conteggiando il numero di divisioni, fino a quando il quoziente non è pari
a zero, in modo tale da ricavare l'ordne del vettore e scindere il numero in cifre*/
quoziente=NrArabo;
do{
quoziente=quoziente/10;
count++;
}while(quoziente!=0);
//instanzio il vettore
VettArabo = new int[count];
//divido il numero in cifre mettendo alla cifra più significativa le migliaia e in quella meno significativa le unità
for(i=(VettArabo.length-1);i>=0;i--){
VettArabo[i] = NrArabo%10;
NrArabo/=10;
}//for
//Conversione
for(i=0;i<VettArabo.length;i++){
if(count==4){ //migliaia
if(VettArabo[i]==1)
NrRomano=NrRomano+"M";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"MM";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"MMM";
}//if count=4
else if (count==3){ //centinaia
if(VettArabo[i]==1)
NrRomano=NrRomano+"C";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"CC";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"CCC";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"CD";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"D";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"DC";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"DCC";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"DCCC";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"CM";
}//if count=3
else if (count==2){ //decine
if(VettArabo[i]==1)
NrRomano=NrRomano+"X";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"XX";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"XXX";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"XL";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"L";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"LX";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"LXX";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"LXXX";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"XC";
}//if count=2
else if (count==1){ //unità
if(VettArabo[i]==1)
NrRomano=NrRomano+"I";
else if(VettArabo[i]==2)
NrRomano=NrRomano+"II";
else if(VettArabo[i]==3)
NrRomano=NrRomano+"III";
else if(VettArabo[i]==4)
NrRomano=NrRomano+"IV";
else if(VettArabo[i]==5)
NrRomano=NrRomano+"V";
else if(VettArabo[i]==6)
NrRomano=NrRomano+"VI";
else if(VettArabo[i]==7)
NrRomano=NrRomano+"VII";
else if(VettArabo[i]==8)
NrRomano=NrRomano+"VIII";
else if(VettArabo[i]==9)
NrRomano=NrRomano+"IX";
}//if count=1
count--;
}//for
return NrRomano;
}//calcolaNumeroRomano
/*@param n di tipo String, rappresenta il la sequenza da controllare se è un numero romano scritto correttamente
@return true se scritto correttamente, false altrimenti*/
public boolean isRomano(String n){
int i=0;
boolean romano = true;
if(n.length()!=0){
//verifica se in n ci sono solo simboli appartenenti all'alfabeto dei numeri romani
while((i<n.length())&&(romano)){
if(!(n.substring(i,i+1).equals("I") || n.substring(i,i+1).equals("V") || n.substring(i,i+1).equals("X") || n.substring(i,i+1).equals("L") || n.substring(i,i+1).equals("C") || n.substring(i,i+1).equals("D") || n.substring(i,i+1).equals("M")))
romano = false;
i++;
}//while
}//if
return romano;
}//isRomano
/*@return il numero arabo dell’oggetto ricevente*/
public int calcolaNumeroArabo(){
int i=0;
//Conversione
while(i<NrRomano.length()-1){
if(NrRomano.substring(i,i+1).equals("M")) //migliaia
NrArabo+=1000;
else if (NrRomano.substring(i,i+1).equals("C")) //centinaia
if(NrRomano.substring(i,i+2).equals("CD")){ //400
NrArabo+=400;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("CM")){ //900
NrArabo+=900;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=100;
else if (NrRomano.substring(i,i+1).equals("D"))
NrArabo+=500;
else if (NrRomano.substring(i,i+1).equals("X")) //decine
if(NrRomano.substring(i,i+2).equals("XL")){ //40
NrArabo+=40;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("XC")){ //90
NrArabo+=90;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=10;
else if (NrRomano.substring(i,i+1).equals("L"))
NrArabo+=50;
else if (NrRomano.substring(i,i+1).equals("I")) //unità
if(NrRomano.substring(i,i+2).equals("IV")){ //4
NrArabo+=4;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else if(NrRomano.substring(i,i+2).equals("IX")){ //9
NrArabo+=9;
i++; //salta un carattere in quanto un numero può essere composto da due cifre
}else
NrArabo+=1;
else if (NrRomano.substring(i,i+1).equals("V"))
NrArabo+=5;
i++; //incrementa posizione successiva
}//while
//Qui si controlla l'ultimo carattere fuori dal while.
//Non controlliamo i caratteri doppi in quanto non ce ne possono
//essere
if(NrRomano.charAt(i)==('M')) //migliaia
NrArabo+=1000;
else if (NrRomano.charAt(i)==('C')) //centinaia
NrArabo+=100;
else if (NrRomano.charAt(i)==('D'))
NrArabo+=500;
else if (NrRomano.charAt(i)==('X')) //decine
NrArabo+=10;
if (NrRomano.charAt(i)==('L'))
NrArabo+=50;
if (NrRomano.charAt(i)==('I')) //unità
NrArabo+=1;
else if (NrRomano.charAt(i)==('V'))
NrArabo+=5;
return NrArabo;
}//calcolaNumeroArabo
}//Romani{}
nonchè la classe di test:
public class TestRomani {
/* classe di test per la classe Studente */
public static void main (String[] args) {
Romani NR; // numero romano
String risposta = "s",tmp; // per leggere le risposte dell’utente
int n;//numero arabo da convertire
/* visualizzazione della finalita’ della classe */
System.out.println("Classe di test per la classe Numeri Romani");
System.out.println();
/* ciclo di test */
while (risposta.equals("s")) {
//conversione da arabo a romano
System.out.print("Numero Arabo: ");
n = Input.readInt();
NR = new Romani(n);
tmp = NR.calcolaNumeroRomano();
if(tmp=="") //si è verificata la condizione di errore
System.out.println("Errore nell'inserimento dei dati.");
else
System.out.println(n+" = "+tmp);
//conversione da romano ad arabo
NR = new Romani(tmp);
n = NR.calcolaNumeroArabo();
if(n==-1)
System.out.println("Errore nell'inserimento dei dati.");
else
System.out.println(tmp+" = "+n);
/* nuova interrogazione dell’utente e lettura della sua risposta */
System.out.print("Vuoi Inserire un nuovo Numero? [s/n] ");
risposta = Input.readString();
System.out.println();
}//while
}//main
}//TestRomani{}
Aiutami cortesemente ke sto uscendo pazzo con sto programma !!!![]()
Giuseppe SPECCHIO
Guarda da qualche errore su qualche numero ,come 45 e alcuni altri.codice:/* classe che gestisce i numeri romani */ public class Romani { private String NrRomano=""; private int NrArabo; private boolean error=false; /* costruisce un oggetto di tipo Romani String Nr.Romano @param s di tipo Individuo, dati anagrafici dello studente corrispondente all’oggetto Romani che si sta costruendo @param n di tipo int, è il numero arabo da convertire */ public Romani(int n) { if((n>0)&&(n<4000)) NrArabo = n; else{ //condizione di errore NrRomano = ""; error=true; } }//Romani public Romani(String s) { if(isRomano(s)) NrRomano=s; else { NrArabo=0; error=true; } } /** @return il riferimento ad un oggetto di tipo String che corrisponde al numero romano il quale rappresentata dall’oggetto ricevente */ public String getNumeroRomano() { return NrRomano; }//getNumeroRomano /** @return il riferimento ad un oggetto di tipo String che rappresenta lo studente corrispondente all’oggetto ricevente */ public String toString() { return NrArabo+" = "+NrRomano; }//toString /**@return il numero romano dell’oggetto ricevente*/ public String calcolaNumeroRomano(){ if(error) return ""; int[] VettArabo; int count=0; //determina la lunghezza del vettore int quoziente,i; //buffer /*dividere il numero arabo per 10, conteggiando il numero di divisioni, fino a quando il quoziente non è pari a zero, in modo tale da ricavare l'ordne del vettore e scindere il numero in cifre*/ quoziente=NrArabo; do{ quoziente=quoziente/10; count++; }while(quoziente!=0); //instanzio il vettore VettArabo = new int[count]; //divido il numero in cifre mettendo alla cifra più significativa le migliaia e in quella meno significativa le unità for(i=VettArabo.length-1;i>=0;i--){ //NON ENTRA NEL CICLO !! VettArabo[i] = NrArabo%10; //System.out.print("VettArabo["+i+"]"+VettArabo[i]); NrArabo/=10; }//for //Conversione for(i=0;i<VettArabo.length;i++){ if(count==4){ //migliaia if(VettArabo[i]==1) NrRomano=NrRomano+"M"; else if(VettArabo[i]==2) NrRomano=NrRomano+"MM"; else if(VettArabo[i]==3) NrRomano=NrRomano+"MMM"; }//if count=4 else if (count==3){ //centinaia if(VettArabo[i]==1) NrRomano=NrRomano+"C"; else if(VettArabo[i]==2) NrRomano=NrRomano+"CC"; else if(VettArabo[i]==3) NrRomano=NrRomano+"CCC"; else if(VettArabo[i]==4) NrRomano=NrRomano+"CD"; else if(VettArabo[i]==5) NrRomano=NrRomano+"D"; else if(VettArabo[i]==6) NrRomano=NrRomano+"DC"; else if(VettArabo[i]==7) NrRomano=NrRomano+"DCC"; else if(VettArabo[i]==8) NrRomano=NrRomano+"DCCC"; else if(VettArabo[i]==9) NrRomano=NrRomano+"CM"; }//if count=3 else if (count==2){ //decine if(VettArabo[i]==1) NrRomano=NrRomano+"X"; else if(VettArabo[i]==2) NrRomano=NrRomano+"XX"; else if(VettArabo[i]==3) NrRomano=NrRomano+"XXX"; else if(VettArabo[i]==4) NrRomano=NrRomano+"XL"; else if(VettArabo[i]==5) NrRomano=NrRomano+"L"; else if(VettArabo[i]==6) NrRomano=NrRomano+"LX"; else if(VettArabo[i]==7) NrRomano=NrRomano+"LXX"; else if(VettArabo[i]==8) NrRomano=NrRomano+"LXXX"; else if(VettArabo[i]==9) NrRomano=NrRomano+"XC"; }//if count=2 else if (count==1){ //unità if(VettArabo[i]==1) NrRomano=NrRomano+"I"; else if(VettArabo[i]==2) NrRomano=NrRomano+"II"; else if(VettArabo[i]==3) NrRomano=NrRomano+"III"; else if(VettArabo[i]==4) NrRomano=NrRomano+"IV"; else if(VettArabo[i]==5) NrRomano=NrRomano+"V"; else if(VettArabo[i]==6) NrRomano=NrRomano+"VI"; else if(VettArabo[i]==7) NrRomano=NrRomano+"VII"; else if(VettArabo[i]==8) NrRomano=NrRomano+"VIII"; else if(VettArabo[i]==9) NrRomano=NrRomano+"IX"; }//if count=1 count--; }//for return NrRomano; }//calcolaNumeroRomano /*@param n di tipo String, rappresenta il la sequenza da controllare se è un numero romano scritto correttamente @return true se scritto correttamente, false altrimenti*/ public boolean isRomano(String n){ int i=0; boolean romano = true; if(n.length()>0){ //verifica se in n ci sono solo simboli appartenenti all'alfabeto dei numeri romani while((i<n.length())&&(romano)){ if(!(n.substring(i,i+1).equals("I") || n.substring(i,i+1).equals("V") || n.substring(i,i+1).equals("X") || n.substring(i,i+1).equals("L") || n.substring(i,i+1).equals("C") || n.substring(i,i+1).equals("D") || n.substring(i,i+1).equals("M"))) romano = false; i++; }//while }//if return romano; }//isRomano /*@return il numero arabo dell’oggetto ricevente*/ public int calcolaNumeroArabo(){ if(error) return -1; int i=0; //Conversione while(i<NrRomano.length()){ //ERRORE: non legge l'ultimo carattere if(NrRomano.substring(i,i+1).equals("M")) //migliaia NrArabo+=1000; else if (NrRomano.substring(i,i+1).equals("C")) //centinaia if(i<NrRomano.length()-1 && NrRomano.substring(i,i+2).equals("CD")){ //400 NrArabo+=400; i++; //salta un carattere in quanto un numero può essere composto da due cifre }else if(i<NrRomano.length()-1 && NrRomano.substring(i,i+2).equals("CM")){ //900 NrArabo+=900; i++; //salta un carattere in quanto un numero può essere composto da due cifre }else NrArabo+=100; else if (NrRomano.substring(i,i+1).equals("D")) NrArabo+=500; else if (NrRomano.substring(i,i+1).equals("X")) //decine if(i<NrRomano.length()-1 && NrRomano.substring(i,i+2).equals("XL")){ //40 NrArabo+=40; i++; //salta un carattere in quanto un numero può essere composto da due cifre }else if(i<NrRomano.length()-1 && NrRomano.substring(i,i+2).equals("XC")){ //90 NrArabo+=90; i++; //salta un carattere in quanto un numero può essere composto da due cifre }else NrArabo+=10; if (NrRomano.substring(i,i+1).equals("L")) NrArabo+=50; if (NrRomano.substring(i,i+1).equals("I")){ //unità if(i<NrRomano.length()-1 && NrRomano.substring(i,i+2).equals("IV")){ //4 NrArabo+=4; i++; //salta un carattere in quanto un numero può essere composto da due cifre }else if(i<NrRomano.length()-1 && NrRomano.substring(i,i+2).equals("IX")){ //9 NrArabo+=9; i++; //salta un carattere in quanto un numero può essere composto da due cifre }else NrArabo+=1; } else if (NrRomano.substring(i,i+1).equals("V")) if(i<NrRomano.length()-1 && NrRomano.substring(i,i+2).equals("VI")) NrArabo+=6; else NrArabo+=5; i++; //incrementa posizione successiva }//while return NrArabo; }//calcolaNumeroArabo }//Romani
Però per tutti gli altri funza.Domani sera o dopo domani lo controllo meglio. Ora non sono nello stato d'animoper farlo.
Le aggiunte sono in rosso.
Ho eliminato pure il codice esterno al whilenon è più utile.
E' bastato aggiungere un controllo prima delle substring(i,i+2)
Lang=Java
Ambiente = Eclipse forever
Ubuntu& Win XP Pro