2013-07-17 28 views
6

Sto cercando di capire come convertire numeri romani in numeri interi. Questa è una parte del mio codice. Quando chiedo all'utente di inserire M mostra 1000, ma quando chiedo all'utente di inserire un numero romano come VM, non mi dà 995 ma 1005. Questo perché sto dicendo al mio programma di fare proprio questo.Sto cercando di capire come convertire numeri romani in numeri interi

Quello che sto cercando di capire è come posso guardare avanti e fargli sapere quando sta aggiungendo o sottraendo numeri romani.

Come iniziare a fare questo?

class Roman 
{ 

    public int inprogress = 0; 
    public Roman(string roman) 
    { 

     char temp = 'Z'; 
     int length; 

     length = roman.Length; 

     for (int i = 0; i < length; i++) 
     { 
      temp = roman[i]; 
      if (temp == 'M') 
      { 
       inprogress = inprogress + 1000; 
      } 
      if (temp == 'D') 
      { 
       inprogress = inprogress + 500; 
      } 
      if (temp == 'C') 
      { 
       inprogress = inprogress + 100; 
      } 
      if (temp == 'L') 
      { 
       inprogress = inprogress + 50; 
      } 
      if (temp == 'X') 
      { 
       inprogress = inprogress + 10; 
      } 
      if (temp == 'V') 
      { 
       inprogress = inprogress + 5; 
      } 
      if (temp == 'I') 
      { 
       inprogress = inprogress + 1; 
      } 
     } 
    } 
} 
+3

il soggetto è "convertire interi in numeri romani", ma il codice sta mostrando "la conversione di numeri romani in numeri interi". Quale stai chiedendo veramente? (Sono contrari.) Per favore [modifica] la tua domanda e chiarisci che cosa stai chiedendo. –

+0

Un piccolo consiglio: quando si programma una soluzione come questa, sarà più facile capire come risolvere il problema, POI codificare quella soluzione. Prendi un pezzo di carta e cerca di trovare un modo per calcolare correttamente i numeri romani per alcuni campioni (usando solo numeri e cose, non stai scrivendo il codice sulla carta!). Quindi, codifica questa soluzione. –

+0

Puoi spiegare che cosa stai guardando 'guarda avanti' e potrei essere anliante per aiutarti? Ps. Stai facendo unsecurity se controlli, utilizzare switch/case o cambiare tutte le istruzioni if ​​ma il primo a 'else' se '. –

risposta

11

il trucco per la conversione di numeri romani è quello di lavorare a ritroso (dalla fine della stringa), non in avanti, lo rende molto più facile.

esempio, se avete IX

  • si inizia con X, = 10
  • mossa indietro 1 .... ora il suo io, io è inferiore a X così ora sottrarre off 1 = 9

una soluzione di riferimento ....

public class RomanNumeral 
    { 
     public static int ToInt(string s) 
     { 
       var last = 0; 
       return s.Reverse().Select(NumeralValue).Sum(v => 
       {      
       var r = (v >= last)? v : -v; 
       last = v; 
       return r; 
       }); 
     } 

     private static int NumeralValue(char c) 
     { 
      switch (c) 
      { 
       case 'I': return 1; 
       case 'V': return 5; 
       case 'X': return 10; 
       case 'L': return 50; 
       case 'C': return 100; 
       case 'D': return 500; 
       case 'M': return 1000;      
      } 
      return 0; 
     } 
    } 

NOTA: questo non convalida i numeri romani, solo convertire quelli che sono già valide.

+1

M non è inferiore a X ..... quindi aggiungerai M –

+0

Ok, "lo rende molto più semplice". Lo accetterò. – user2246674

+0

degno di nota, questo è un classico kata di codifica (insieme al gioco di bowling) http://codingdojo.org/cgi-bin/wiki.pl?KataRomanNumerals –

0

È necessario aggiungere una logica che in pratica dice che se la V è prima della M, quindi sottrarla. In base a questa riga:

if (temp == 'V') { inprogress = inprogress + 5;

1
List<Level> levels = new List<Level>(); 
    int[] val = new int[255]; 
    private void Form1_Load(object sender, EventArgs e) 
    { 

     val[(byte)'I'] = 1; 
     val[(byte)'V'] = 5; 
     val[(byte)'X'] = 10; 
     val[(byte)'L'] = 50; 
     val[(byte)'C'] = 100; 
     val[(byte)'D'] = 500; 
     val[(byte)'M'] = 1000; 
     levels.Clear(); 
     levels.Add(new Level('I', 'V', 'X')); 
     levels.Add(new Level('X', 'L', 'C')); 
     levels.Add(new Level('C', 'D', 'M')); 
    } 
    int fromRoman(string n) 
    { 
     n = n.ToUpper(); 

     var result = 0; 
     var lastDigit = 0; 
     for (var pos = n.Length - 1; pos >= 0; pos--) 
     { 
      var curDigit = val[(byte)n[pos]]; 


      if (curDigit >= lastDigit) 
       result += curDigit; 
      else 
       result -= curDigit; 

      lastDigit = curDigit; 
     } 

     return result; 
    } 
    public class Level 
    { 
     public Level(char i, char v, char x) 
     { 
      this.i = i; 
      this.x = x; 
      this.v = v; 
     } 
     public char i; 
     public char v; 
     public char x; 
    } 

quindi eseguire

int Result = fromRoman("X"); 
+0

Perché convertite 'char's in' byte's? – Guillaume

+0

Perché devo dare un numero di indice all'elemento nell'array. – halit

Problemi correlati