[LeetCode-13] Roman to Integer(罗马数字转成阿拉伯数字)

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.

【分析】罗马数字共有7个,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。按照下述的规则可以表示任意正整数。需要注意的是罗马数字中没有“0”。一般认为罗马数字只用來计数,而不作演算。

右加左減:
在较大的罗马数字的右边记上小的罗马数字,表示大数字加小数字。
在较大的罗马数字的左边记上小的罗马数字,表示大数字减去小数字。
左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV
但是,左减不能跨去一个位数。比如,99不可以用IC(100 - 1)表示,而是用XCIX([100 - 10] + [10 - 1])表示。(等同于阿拉伯每位数字表示每位)
左减数字必须为一位,比如8写成VIII,而非IIX。
右加数字不可连续超过三位,比如14写成XIV,而非XIIII。(見下方“数码限制”一項。)

左减右加算法思想:

不难发现,罗马数字是没有禁止,我建议大家可以先试着从I数到C,这样便对罗马数字有个了解,然后发现其为纯粹叠加而成的,所以用户输入一个数后,我们可以来遍历这个数,用sum来总计和,比较pre (s[i-1]) 和 cur (s[i]),如果,cur 比 pre 小的话,直接相加,如果 cur 比 pre 大的话,则将总和sum减去pre这个地方数的两倍,同时加上 cur 就相当于后边的数比左边的数大,则用右边的数减左边的数。但因为之前已经加过一次了,所以减两次。
代码实现:

int charTointValue(char c)
{
    int data = 0;

    switch (c) {
        case 'I':
            data = 1;
            break;
        case 'V':
            data = 5;
            break;
        case 'X':
            data = 10;
            break;
        case 'L':
            data = 50;
            break;
        case 'C':
            data = 100;
            break;
        case 'D':
            data = 500;
            break;
        case 'M':
            data = 1000;
            break;
    }

    return data;
}


int romanToInt(char* s) {
    if(!s)
        return 0;
    int len = strlen(s);
    int i = 0;
    int sum = 0;
    int pre = 0;
    int cur = 0;
    sum = charTointValue(s[0]); /*第一个值*/

    for(i = 1;i < len;i ++) {
        pre = charTointValue(s[i-1]);
        cur = charTointValue(s[i]);
        if(cur <= pre) {
            sum = sum + cur;
        } 
        else {
            sum = sum - 2*pre + cur;
        }
    }
    return sum; 
}

你可能感兴趣的:(LeetCode_Easy)