Roman numerals to integers

前端 未结 14 928
不思量自难忘°
不思量自难忘° 2020-12-05 20:56

I have a transfer with products that unfortunately has to get matched by product name. The biggest issue here is I might get duplicate products on account of roman numbers.

14条回答
  •  星月不相逢
    2020-12-05 21:25

    A more simple and readable C# implementation that:

    • maps I to 1, V to 5, X to 10, L to 50, C to 100, D to 500, M to 1000.
    • uses one single foreach loop (foreach used on purpose, with previous value hold).
    • adds the mapped number to the total.
    • subtracts twice the number added before, if I before V or X, X before L or C, C before D or M (not all chars are allowed here!).
    • returns 0 (not used in Roman numerals) on empty string, wrong letter or not allowed char used for subtraction.
    • remark: it's still not totally complete, we didn't check all possible conditions for a valid input string!

    Code:

    private static Dictionary _romanMap = new Dictionary
    {
       {'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}
    };
    
    public static int ConvertRomanToNumber(string text)
    {
        int totalValue = 0, prevValue = 0;
        foreach (var c in text)
        {
            if (!_romanMap.ContainsKey(c))
                return 0;
            var crtValue = _romanMap[c];
            totalValue += crtValue;
            if (prevValue != 0 && prevValue < crtValue)
            {
                if (prevValue == 1 && (crtValue == 5 || crtValue == 10)
                    || prevValue == 10 && (crtValue == 50 || crtValue == 100)
                    || prevValue == 100 && (crtValue == 500 || crtValue == 1000))
                    totalValue -= 2 * prevValue;
                else
                    return 0;
            }
            prevValue = crtValue;
        }
        return totalValue;
    }
    

提交回复
热议问题