Why this displays 5 for "IV" input?

class Program
{
    static void Main(string[] args)
    {
               /*
                I              1
                V             5
                X             10
                L             50
                C             100
                D             500
                M             1000
               */

            string str;
            int cnt = 0, i = 0;
            str = Console.ReadLine();
            while (i<str.Length)
            {
                if (str[i] == 'M')
                    cnt = cnt + 1000;
                if (str[i] == 'D')
                    cnt = cnt + 500;
                if (str[i] == 'C')
                    cnt = cnt + 100;
                if (str[i] == 'L')
                    cnt = cnt + 50;
                if (str[i] == 'X')
                    cnt = cnt + 10;

                if (str[i] == 'I' && str[i + 1] == 'V')
                    cnt = cnt + 4;
                else
                    if (str[i] == 'I' && str[i + 1] != 'V')
                        cnt = cnt + 1;

                if (str[i] == 'V' && str[i - 1] == 'I')
                    cnt = cnt + 0;
                else
                    if (str[i] == 'I' && str[i + 1] != 'I')
                        cnt = cnt + 1;
                i++;

            }

            Console.WriteLine(cnt);

    }
}

Please Tell us what’s happening in your own words.

Learning to describe problems is hard, but it is an important part of learning how to code.

Also, the more you say, the more we can help!

I’m trying to transform roman numbers to integers. This is a bug.

What is a bug? How do we see the bug? What have you tried so far to fix the bug?

I should get “4” for the “IV” input. On paper with pen but no luck so far. It’s my try for the https://leetcode.com/problems/roman-to-integer/ problem.

Hi florea,

While I agree with JeremyLT about you describing the problem in your own words, I will give you some hints, but I am not going to provide code that may (or may not) correctly give 4 for the input of IV.

The code you have is ok, not great, but ok.

As to why your code displays 5 for IV, I can see why it is displaying 5. My suggestion would be to, with your pen and paper.

Go through each numeral from 1 to 4, (i to iv), and write down every step that the code goes through for each number.

Here is start to what I mean.
str = “I” // So we have the number 1
while (i<str.Length) — What does i equal? Is i less than str.Length?
// i = 0 // 0 is less than 1
if (str[i] == ‘M’) // This would be false, move on.
if (str[i] == ‘D’) // This would be false, move on.
if (str[i] == ‘C’) // This would be false, move on.
if (str[i] == ‘L’) // This would be false, move on.
if (str[i] == ‘X’) // This would be false, move on.

if (str[i] == ‘I’ && str[i + 1] == ‘V’) // what does str[i] == ‘I’ compute to?
// What does str[i +1] == ‘V’ compute to.
// Let us say, str[i] == ‘I’ is true, but str[i + 1]== ‘V’ is false, then the entire if is false, move on.
else
if (str[i] == ‘I’ && str[i + 1] != ‘V’)
// Again, let us say str[i] == ‘I’ is true, but str[i + 1] != ‘V’ is false, then the entire if is false, move on.

if (str[i] == ‘V’ && str[i - 1] == ‘I’) // str[i] == ‘V’ is false, so the entire if is false, move on.
else
if (str[i] == ‘I’ && str[i + 1] != ‘I’) // str[i] == ‘I’ is true, but str[i + 1] != ‘I’ is false, so the entire if is false.
i++ // This makes i == 1
Then back at the while statement, as the input it “I” only, with a length of 1, the while statement is false.
The while block of code, between the 2 { }'s is bypassed (not run), and we come to:
Console.WriteLine(cnt);

What would cnt be at this stage?
Then go through “II” and “III” and “IV”, with your pen and paper, and find out what cnt is at each stage.

The first problem is trying to work out how Roman Numerals work to start with.

For instance, the first rule would be how the numerals calculate to decimal.

i = 1, ii = 2, iii = 3, then
iv = 4.
v = 5.
vi = 6, vii = 7, viii = 8.

From here, hopefully you can see a pattern forming:

There are up to 3 Roman Numerals before the next number is displayed differently.

That is, there are 3 i’s before the i gets put before the next major numeral, being the v for 5.

The same thing happens after 5, where 6 (vi) has a 5 a v then a 1 an i, 7 (vii) has a v then 2 i’s, 8 (viii) has a v then 3 i’s.

9 then changes again to an i before the new major numeral, being an x (ix).

10 is the x, and the above process starts again, just with a 10 an (x) in front of it.

11 = xi, 12 = xii, 13 = xiii, 14 = xiv, 15 = xv, 16 = xvi, 17 = xvii, 18 = xviii, and 19 = xix

Then the 20’s are the same, except you have an extra x at the front. The 30’s have 3 x’s.

Hitting 40, the first rule applies again…There are only 3 Roman Numerals of the same type allowed before the format is changed.

40 = xl, as l = 50.

You will need to do some logic to work out how to read the inputted Roman Numerals.

This can be done several ways, an example being.

Find out how long the input string (str) is.

If the length is only 1
The result (cnt) is the value of this 1 numeral.

If the length is longer than 1
Do I check if the first numeral is lower or greater than the next numeral?
This would happen if the input (str) is iv, as the i is lower then the v.

If the first numeral is not lower than the next numeral, then you could potentially add the value of this numeral to the result (cnt).

If the first numeral is lower than the next numeral, what do I do?
Some example of this case would be 9 = ix. The i is lower than the x.

What about 99? xcix where the 1st numeral is lower than the second numeral, but, the 3rd numeral is lower than both the 2nd numeral and the 4th numeral.

Therefore, some thinking about how to read the characters of the input string (str) is necessary, as well as how to be able to see if the current character/numeral (str[i]) in your current code represents a Roman Numeral that is greater or lower than the next character/numeral in str?

A hint would be how you change characters in a string. For instance, the string is “21”, but you want to make it “12”.
You need a variable to store the 2, plus you may or may not need a variable to store the 1.

char first = str[0]; // Which is the ‘2’.
str[1] = first;

What is wrong with this?

Where is the ‘1’ that was is str[1] now?

It has been overwritten by the first, so your string currently would be “22”, as str[0] == 2 and str[1] == 2.

You may or may not need to have another variable to (temporarily) hold one of the two numbers, whether it be the ‘2’ or the ‘1’.

The above code would need to change to:

char first = str[0]; // Which is ‘2’
char temp = str[1]; // Which is ‘1’
str[0] = temp; // The ‘1’
str[1] = first; // Which is ‘2’

or

char first = str[0]; // Which is ‘2’ again.
str[0] = str[1]; // Which is ‘1’
str[1] = first; // Which is ‘2’

Using this as an example, you will need to work out the logic of how to check 1 Roman Numeral against another Roman Numeral, then you can find out the correct value of the Roman Numeral.

This coding example really makes you think about how you are going to do it, in other words, what logic you are going to use to produce the correct answers.

In further, look into what

array index out of bounds

means, as this will help you, in the future, and also for this problem.