Question: Convert a roman numeral to an integer. The input is guaranteed to be within the range from 1 to 3999.
Solution:
Scan from the end of the string to its start. We need to determine if we should subtract or add the int of current char. We set a flag representing the sign of the current int. With the flag determining the sign, we could safely add cur_int * flag into our current sum. How we set the flag is described as following:
Initially we are at the end of the string. We always add the end of the string. Set cur_flag as 1;
In the iteration:
If the current char is a int larger than the int of its left, then we need to subtract its left in the next iteration, and thus set the flag for the next char as -1. Otherwise we set it as 1.
Code:
class Solution {
public:
int romanToInt(string s) {
//char unit[] = {'I','V','X','L','C','D','M'};
//1, 5,10,50,100,500,1000
int res = 0;
int cur_flag = 1;//cur_flag is set as 1 since we always add s.at(end);
int cur;
int i = s.length()-1;
while(i-1>=0){
cur = get_num(s.at(i));
if(cur==-1) return -1;
<span style="white-space:pre"> </span>res+=cur*cur_flag;//number * sign
if(cur>get_num(s.at(i-1))) cur_flag = -1;//if our current number is larger than its left, its left should be subtracted
else cur_flag = 1;
i--;
}
res+= get_num(s.at(0))*cur_flag;
return res;
}
int get_num(char c){
int res = 0;
switch(c){
case 'I': res = 1;break;
case 'V': res = 5; break;
case 'X': res = 10; break;
case 'L': res = 50; break;
case 'C': res = 100; break;
case 'D': res = 500; break;
case 'M': res = 1000; break;
default: res = -1; break;
}
return res;
}
};