问题
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;
}
}
}
}
回答1:
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.
回答2:
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;
}
Then Run
int Result = fromRoman("X");
回答3:
You need to add logic that basically says that if the V is before the M then subtract it. Based on this line here:
if (temp == 'V') { inprogress = inprogress + 5;
来源:https://stackoverflow.com/questions/17711746/i-am-trying-to-figure-out-how-to-convert-roman-numerals-into-integers