[One question per day] Roman numerals to integers

https://leetcode-cn.com/problems/roman-to-integer/Roman
numerals to integers
Roman numerals contain the following seven characters: I, V, X, L, C, D and M.

Character value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
For example, the Roman numeral 2 is written as II, which is two parallel 1. 12 is written as XII, which is X + II. 27 Write XXVII, which is XX + V + II.

Normally, the small number in Roman numerals is to the right of the large number. But there are special cases, for example, 4 is not written as IIII, but IV. The number 1 is to the left of the number 5, and the number represented is equal to the number 4 obtained by reducing the number 1 by the number 5. Similarly, the number 9 is represented as IX. This special rule only applies to the following six situations:

I can be placed to the left of V (5) and X (10) to represent 4 and 9.
X can be placed to the left of L (50) and C (100) to indicate 40 and 90.
C can be placed to the left of D (500) and M (1000) to indicate 400 and 900.
Given a Roman numeral, convert it to an integer. The input must be in the range of 1 to 3999.

Example 1:

Input: "III"
Output: 3
Example 2:

Input: "IV"
Output: 4
Example 3:

Input: "IX"
Output: 9
Example 4:

Input: "LVIII"
Output: 58
Explanation: L = 50, V = 5, III = 3.
Example 5:

Input: "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90, IV = 4.


Solution 1

Use map.
The key is a single letter of Roman numerals, and val is the corresponding value.
Needs to determine the key corresponding to what is now val is not less than the next key corresponding val, such as IVfour instead of six.
40ms 9.1mb, it takes time to construct the map, the following operation time complexity is O (n).

class Solution {
public:
    int romanToInt(string s) {
        map<char, int> m = {
        	{'I', 1},
        	{'V', 5},
        	{'X', 10},
        	{'L', 50},
        	{'C', 100},
        	{'D', 500},
        	{'M', 1000},
        };

        int ret = 0;
        for (int i = 0; i < s.size(); ++i) {
        	if (m[s[i]] < m[s[i + 1]]) {
        		ret = ret - m[s[i]];
        	} else {
        		ret = ret + m[s[i]];
        	}
        }

        return ret;
    }
};

Solution 2

The solution of netizens is 4ms 5.6mb,

#define nI 1  //直接用define I 1,好像会有歧义
#define nV 5 
#define nX 10
#define nL 50
#define nC 100
#define nD 500
#define nM 1000

int romanToInt(char* s) 
{ 
    int num = 0, flag = 0;   /*立一个flag,是因为之前我在后面会用三个if,一个else,其实我的初衷是三个if有其中任何一个满足都不要再执行else了
	                         但是如果没有flag的话,意思是第三个if如果不成立便会跳去else,比如IV,第一个if满足,然后第三个if不满足,else这时候
							 就会出来执行,很不爽*/
    while(*s != NULL)
    {
        if(*s == 'I' && (*(s + 1) == 'V' || *(s + 1) == 'X'))     //接下来的这三个if都有特殊含义,所以flag=1,普通情况属于flag=0
        {
			flag = 1;
            switch(*(s + 1))
            {
                case 'V':num += (nV - nI); s+=2; break;
                case 'X':num += (nX - nI); s+=2; break;
            }
        }
        if(*s == 'X' && (*(s + 1) == 'L' || *(s + 1) == 'C'))
        {
			flag = 1;
            switch(*(s + 1))
            {
                case 'L':num += (nL - nX); s+=2; break;
                case 'C':num += (nC - nX); s+=2; break;
            }
        }
        if(*s == 'C' && (*(s + 1) == 'D' || *(s + 1) == 'M'))
        {
			flag = 1;
            switch(*(s + 1))
            {
                case 'D':num += (nD - nC); s+=2; break;
                case 'M':num += (nM - nC); s+=2; break;
            }
        }
        if(flag == 0)   //本来这里是else的,改为if(flag == 0)
        {
            switch(*s)
            {
                case 'I':num += nI; s += 1; break;
                case 'V':num += nV; s += 1; break;
                case 'X':num += nX; s += 1; break;
                case 'L':num += nL; s += 1; break;
                case 'C':num += nC; s += 1; break;
                case 'D':num += nD; s += 1; break;
                case 'M':num += nM; s += 1; break;
            }
        }
		flag = 0;  //最后置回普通状态
    }
    return num;
}

EOF

98 original articles have been published · 91 praises · 40,000+ views

Guess you like

Origin blog.csdn.net/Hanoi_ahoj/article/details/105299608