LeetCode(13) RomanToInteger

Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.

本题是把一个罗马数字转化为阿拉伯数字,和前道题目正好相反。我按照千位、百位、十位、个位的顺序依次处理罗马数字。在前一到题目的解答中,可以找到一个办法去简化代码,本题好像不怎么方便找到合适的简化方法。

class Solution {
public:
    int romanToInt(string s) {
        int result=0;
        const char* p=s.c_str();
        int count=0;
        
        //千位
        while(*p!='\0'&&*p=='M'){
            p++;//千位循环结束后p指向百位。
            count++;
        }
        result+=1000*count;
        count=0;
        
        //百位
        if(*p=='C'){
            while(*p!='\0'&&*p=='C'){
                p++;
                count++;
            }
            if(count==1&&*p=='M'){
                p++;
                count=9;
            }
            else if(count==1&&*p=='D'){
                p++;
                count=4;
            }
        }else if(*p=='D') {
            p++;
            count=5;
            while(*p!='\0'&&*p=='C'){
                p++;
                count++;
            }

        }else{
            count=0;
        }
        result+=count*100;
        count=0;
        
        
        //十位
        if(*p=='X'){
            while(*p!='\0'&&*p=='X'){
                p++;
                count++;
            }
            if(count==1&&*p=='C'){
                p++;
                count=9;
            }
            else if(count==1&&*p=='L'){
                p++;
                count=4;
            }
        }else if(*p=='L') {
            p++;
            count=5;
            while(*p!='\0'&&*p=='X'){
                p++;
                count++;
            }
            
        }else{
            count=0;
        }
        result+=count*10;
        count=0;
        
        
        //个位
        if(*p=='I'){
            while(*p!='\0'&&*p=='I'){
                p++;
                count++;
            }
            if(count==1&&*p=='X'){
                p++;
                count=9;
            }
            else if(count==1&&*p=='V'){
                p++;
                count=4;
            }
        }else if(*p=='V') {
            p++;
            count=5;
            while(*p!='\0'&&*p=='I'){
                p++;
                count++;
            }
            
        }else{
            count=0;
        }
        result+=count;
        
        return result;
    }
};

update1 : 2014-10-06

上面的解法太繁琐太深入细节了,观察到罗马数字和Integer的转换的小规律是:

IV = 5 -  1 =  (-1) + 5 = 4

VI = 5 + 1 = 5 + 1 = 6

I在V前面,由于I比V小,所以I被解释为负数。

V在I后面,由于V比I大,所以V给解释为整数。

继续看几个例子。

VII = 5 + 1 + 1 = 7

 IX = (-1) + 10 = 9

所以,可以一次把输入字符串扫描一遍,从第一个字符开始,到最后一个字符为止,一次比较当前字符a和当前字符的下一个字符b。如果a< b ,解释为 b - a,否则如果a >= b, 解释为a + b。 实际上,由于每次总是比较2个相邻的字符,所以是下标是从0开始,到inputstring.length()-2结束。


代码如下:

class Solution {
public:
    int romanToInt(std::string s) {
        int sum = 0;
        int start = 0;

        char char_arr[] = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};
        int int_arr[] = {1, 5, 10, 50, 100, 500, 1000};
        std::map roman_map;
        int map_len = sizeof(char_arr)/sizeof(char); 
        for (int i = 0; i< map_len; ++i) 
            roman_map.insert(std::pair (char_arr[i], int_arr[i]));
        for (int i = 0; i < s.length() - 1; ++i) {
            if (roman_map[s[i]]>=roman_map[s[i + 1]])
                sum += roman_map[s[i]];
            else
                sum -= roman_map[s[i]];
        }
        sum += roman_map[s[s.length()-1]];
        return sum;
    }
};


你可能感兴趣的:(C++,LeetCode(C++))