Roman to Integer

https://leetcode.com/problems/roman-to-integer/

罗马数字转整数,罗马数字类型是{'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000} 规则是如果把低级别的数放在高级别的左边就是‘减去’,如果放在右边就是‘加上’。

我试了两个方法,第一个是直接把罗马数字的字符串转换成一个整型数组,然后遍历数组,如果当前数字比前一个大就把前一个变成负数。遍历完后把数组sum 起来就是结果。

/**
 * @param {string} s
 * @return {number}
 */
var romanToInt = function(s) {
    var roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000};
    var ints = [];
    var len = s.length;
    var minusValid = true;
    for (var i = 0; i < len; i++) {
        ints.push(roman[s[i]]);
    }
    for (var i = 1; i < len; i++) {
        if (ints[i] > ints[i-1]) {
            if (!minusValid) {return false;}
            ints[i-1] = -ints[i-1];
            minusValid = false;
        } else {
            minusValid = true;
        }
    }
    // console.log(ints);
    return ints.reduce(function(acc, o) {
        return acc + o;
    });
};

另一个方法是看别人答案发现的,发现如果倒过来遍历字符串的话就不用把整个字符串全转成数组存起来了,只用边遍历边累加,遇到比前一个小的就是减。

    var roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000};
    var len = s.length;
    var ret = roman[s[len - 1]];
    for (var i = len - 2; i >= 0; i--) {
        if (roman[s[i]] < roman[s[i+1]]) {
            ret -= roman[s[i]];
        } else {
            ret += roman[s[i]];
        }
    }
    return ret;

但是两个方法都没有处理非法罗马数字的情况,比如IIV IVX 这种写法是错误的,原因是不能在左边连续减两个数。

原文地址:https://www.cnblogs.com/agentgamer/p/6900115.html