Zoro Zoro - 3 months ago 11
C# Question

I am trying to figure out how to convert roman numerals into integers

I am trying to figure out how to convert roman numerals to integers. This is a portion of my code. When I prompt the user to enter M it shows 1000, but when I prompt the user to enter a roman numeral such as VM, it does not give me 995 but instead 1005. This is because I am telling my program to do just that.

What I am trying to figure out is how I can look ahead and get it to know when it is adding or subtracting roman numerals.

How do I begin to go about doing this?

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;
}
}

}



}


}

Answer

the trick to converting roman numerals is to work backwards (from the end of the string) not forwards, makes it a lot easier.

eg, if you have IX

  • you start with X, = 10
  • move back 1.... now its I, I is less than X so now subtract off 1 = 9

A reference solution....

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;
        }
    }

NOTE: this doesn't validate roman numerals, just convert ones that are already valid.