Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    Da Numero Romano ad Arabo

    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

  2. #2
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    4
    gia che ci sei anche a me serviva una cosa del genere...

  3. #3
    ma non date risposte del genere fate perdere solo del tempo
    Giuseppe SPECCHIO

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577

  5. #5

    ci siamo quasi...

    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

  6. #6
    Utente di HTML.it
    Registrato dal
    Mar 2002
    Messaggi
    315
    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.
    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.
    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

  7. #7

    grazie ma... non è finita qui

    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

  8. #8
    /* 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

  9. #9

    qualche mofifica...

    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

  10. #10
    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
    Guarda da qualche errore su qualche numero ,come 45 e alcuni altri.
    Però per tutti gli altri funza.Domani sera o dopo domani lo controllo meglio. Ora non sono nello stato d'animo per farlo.

    Le aggiunte sono in rosso.
    Ho eliminato pure il codice esterno al while non è più utile.
    E' bastato aggiungere un controllo prima delle substring(i,i+2)
    Lang=Java
    Ambiente = Eclipse forever
    Ubuntu & Win XP Pro

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.