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

3

7

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;
            }
        }
    }
}
Elishaelision answered 17/7, 2013 at 23:2 Comment(5)
Your subject is "convert integers into roman numerals", but your code is showing "converting roman numerals into integers". Which one are you actually asking? (They're opposites.) Please edit your question and clarify which you're asking.Abixah
A bit of advice: when programming a solution like this, it will be easier if you figure out HOW you're going to solve the problem, THEN code that solution. Take out a piece of paper and try to come up with a way to calculate the roman numerals correctly for some samples (just using numbers and stuff, you're not writing code on the paper!). Then, code that solution.Terylene
Could you explain what you meen by 'look ahead' and I might be anledning to help you out? Ps. You are doing uneccesary if checks, either use switch/case or change all if statements but the first to ''else if'.Stria
roman numerals into integers is what I meant.Elishaelision
BTW, the subtractive principle like "IV" meaning 4 was not used by the Romans circa 1 AD. The subtractive usage came much later (about 13th century). In "Roman" times, a IV and VI meant the same thing: 6. It was more about artistry than position. Thus the OP approach that does not take into account this subtractive principle is more "Roman" and less European.Ganda
W
14

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.

Workroom answered 17/7, 2013 at 23:4 Comment(11)
also worth noting, this is a classic coding kata ( along with the bowling game ) codingdojo.org/cgi-bin/wiki.pl?KataRomanNumeralsWorkroom
This problem might be too difficult for me to do. It isn't for a grade but I thought it was neat out of the book. I believe I dont know enough about the language to do it.Elishaelision
its a good problem, you only need to know loops and if statements, it just can feel frustrating at the beginning. The struggle is important, because you have "Aha" moments, and then things begin to make more senseWorkroom
I realize 4 weeks isn't any real amount of time to code. Here is something that I am doing wrong. I make if('I' < 'V'){ inprogress = inprogress -1;} I am essentially saying that if 1 is less then 5 then subtract 1... how can I make it if what I type in is less than the roman numeral above it, then subtract? If that makes any sense.... I know what I want it it to do I just dont know how to tell the computer!Elishaelision
@user2593398 I have your answer belowFanjet
everyones goes through (even after lots of experience!) the self talk along the lines ... "this is too hard!" "why isn't this stuff simpler? why is it so complicated! argh!" "I'm too dumb for this" "why won't it work? what the hell does this mean? it should work!!" etc etc etcWorkroom
@AMR its not about an answer, its about how he can solve it himself.Workroom
@AMR also, your answer needs some improvement, its kind of...hmmm...messyWorkroom
I am still working on my own version. I realize the trick is keeping track of the number in front and the number behind. Mine looks more like a bunch of if statements... not the cleanest code but I've only done this for 6 weeks now....Elishaelision
Also for anyone who reads this in the future... It is best not to take an intro into C# for a summer course as covering methods, if statements, loops, arrays, etc is just not enough time for someone who has never programmed before. These boards help me soooo much.Elishaelision
@Azzamean that's cool, doesn't matter if its the hugest mess ever! once you have something working, you can try playing with it to make it simpler.Workroom
H
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;
    }

Then Run

int Result =  fromRoman("X");
Hydrostat answered 17/7, 2013 at 23:37 Comment(2)
Why do you convert chars to bytes?Varicolored
Because I have to give an index number to element in the array.Hydrostat
M
0

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;

Monro answered 17/7, 2013 at 23:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.