I dont understand why my Java code isnt reading IX as 9 but is reading LIX as 59

Viewed 65

I am trying to create some code to read roman numerals and turn them into an integer. the issue im having is the 9s and 4s. I am able to get it to read if the 9 or 4 is inside a number (I.E LIV is 54 and LXI is 59) but by its self (IV and IX) it only reads 6 and 11. here is my code:

public static void RomantoInt(String s) {
    HashMap<Character, Integer> RomanNums = new HashMap<>();
    int count = 0;

    RomanNums.put('I', 1);
    RomanNums.put('V', 5);
    RomanNums.put('X', 10);
    RomanNums.put('L', 50);
    RomanNums.put('C', 100);
    RomanNums.put('D', 500);
    RomanNums.put('M', 1000);


    LinkedList<Character> UserInput = new LinkedList<>();

    //Adds Each numeral to the Array
    for (int i = 0; i < s.length(); i++) {
        char userint = s.charAt(i);
        UserInput.add(userint);
    }

    //loop through the array backwards and adds up the count.
           for(int j =UserInput.toArray().length -1; j> -1 ; j--) {
               int grab = RomanNums.get(UserInput.get(j));
               count += grab;

   // Checks for 4s and 9s.

               if(grab == RomanNums.get('X') && (j - 1) == RomanNums.get('I')) {
                   count -= 2;
               }
    }
    System.out.println(count);
2 Answers

Comparing j - 1 -- which is a position in a string -- to the value of a roman numeral does not seem to make any sense.

Specifically, it only works when the roman 'I' is the second character, exactly.

What you really want to be testing is whether the character at the (j-1)'th position is 'I'.

The correct formulation should be something like

if (grab == RomanNums.get('X') &&
    j > 0 &&
    UserInput.get(j-1) == 'I') ...

This was my solution for leetcode: https://leetcode.com/problems/roman-to-integer/

You have the right idea about reading the input backwards and one loop should be enough to get the job done.

All you need to do is account for the cases when you have to subtract the roman numeral, and you can do that by keeping track of the previous roman numeral for comparison.

For example when input string is: "IX"

We start at 'X' in the first iteration and since previous is equal to '?' we just add 10 and set previous to 'X'. Now when we attempt to sum up 'I' in the next iteration, we look at previous and notice that it is an 'X' and instead of adding 1 to the running sum , we should subtract 1. The total should be 9.

public int romanToInt(String s) {
        int sum = 0;
        char prev = '?';
        
        for(int i = s.length()-1;i >= 0;i--)    {
            
            switch(s.charAt(i))    {
                case 'I'    : sum += prev == 'V' || prev == 'X' ? -1 : 1;
                    break;
                case 'V'    : sum += 5;
                    break;
                case 'X'    : sum += prev == 'L' || prev == 'C' ? -10 : 10;
                    break;
                case 'L'    : sum += 50;
                    break;
                case 'C'    : sum += prev == 'D' || prev == 'M' ? -100 : 100;
                    break;
                case 'D'    : sum += 500;
                    break;
                case 'M'    : sum += 1000;
                    break;
                default     : 
                    break;
            }
            prev = s.charAt(i);
        }
        return sum;        
    }
Time complexity is O(n) - Iterated the length of the input string
Space complexity is O(1) - No additional data structure was needed
Related