0

In almost all examples are about converting roman numbers to integer. Does it make sense to convert one by one all roman numbers and then check if that number is a greater than 0?

Quince
  • 144
  • 11
  • Do you have a sample input string which you want to check if it's a roman number? Normally roman numbers uses limited number of alphabets such as I, V, X, C, L D, C M... if your string contains any character other than these, you can consider it as a non-roman number string. – Chetan Feb 26 '20 at 02:58
  • https://stackoverflow.com/questions/1390749/check-if-a-string-contains-one-of-10-characters – Chetan Feb 26 '20 at 03:09
  • There's also the issue that `IIIIIV` is not a roman numeral. You'd have to study the roman numeral system and find the rules of creating numerals. – JMadelaine Feb 26 '20 at 03:28
  • have you seen https://www.geeksforgeeks.org/converting-roman-numerals-decimal-lying-1-3999/ ? They have a C# implementation – JMadelaine Feb 26 '20 at 03:30

2 Answers2

2

Not sure if you can find anything form the box. To create own function :

private static Dictionary<char, int> _romanMap = new Dictionary<char, int>
{
   {'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}
};


public static int IsRoman(string text) {
  foreach (var c in text) 
      if (!_romanMap.ContainsKey(char))
          return 0;
   return 1 
 }
Eugene
  • 1,487
  • 10
  • 23
  • 1
    This falls apart when you input `IIIIIV`, as it is not a Roman numeral. – JMadelaine Feb 26 '20 at 03:31
  • @Madelaine - Now I see, JMadelaine says absolutely right. – Quince Feb 26 '20 at 03:33
  • You are right. Additional validation logic is required. To avoid duplication, check this link out: https://stackoverflow.com/questions/14900228/roman-numerals-to-integers – Eugene Feb 26 '20 at 03:42
2

You could do something like this... Not pretty but...

public class Solution {
    public int RomanToInt(string s) {

        var total = 0;
        var currentNumber = 0;
        var lastNumber = 0;
        var lastRoman = '/';

        // Take results from 's' and iterate through chars
        foreach (var roman in s)
        {
            if (roman.Equals('I'))
            {
                currentNumber = 1;
            }
            else if (roman.Equals('V'))
            {
                currentNumber = 5;   
            }
            else if (roman.Equals('X'))
            {
                currentNumber = 10;       
            }
            else if (roman.Equals('L'))
            {
                currentNumber = 50;                 
            }
            else if (roman.Equals('C'))
            {
                currentNumber = 100;          
            }
            else if (roman.Equals('D'))
            {
                currentNumber = 500;  
            }
            else if (roman.Equals('M'))
            {
                currentNumber = 1000;
            }
            // Account for edge cases
            if (roman.Equals('V') && lastRoman.Equals('I') || roman.Equals('X') && lastRoman.Equals('I') || // I can be placed before V (5) and X (10) to make 4 and 9. 
                roman.Equals('L') && lastRoman.Equals('X') || roman.Equals('C') && lastRoman.Equals('X') || // X can be placed before L (50) and C (100) to make 40 and 90. 
                roman.Equals('D') && lastRoman.Equals('C') || roman.Equals('M') && lastRoman.Equals('C') )  // C can be placed before D (500) and M (1000) to make 400 and 900.
            {
                var subtract = currentNumber - lastNumber;                 
                total = total - lastNumber + subtract;                        
            }
            else
            {
                total = currentNumber + total;     
            }

            lastRoman = roman;
            lastNumber = currentNumber;
        }

        return total;
    }
}

I haven't tested this extensively, but it passed the leetcode check a while back when I wrote it.

iamtravisw
  • 321
  • 1
  • 3
  • 16