leetCode算法题:罗马数字转整数。
要求:
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
一开始看到这道题的时候,发现它的通过率还是蛮高,想着应该还是很简单的。可是发现真正在写代码的时候有很多很多问题出现。差不多花了我一天的事件吧,才搞定这道题。
首先罗马数字拼写规则
- 罗马数字共有7个,即
Ⅰ
(1)、Ⅴ
(5)、Ⅹ
(10)、Ⅼ
(50)、Ⅽ
(100)、Ⅾ
(500)和Ⅿ
(1000)。按照下述的规则可以表示任意正整数。需要注意的是罗马数字中没有“0”,与进位制无关。一般认为罗马数字只用来记数,而不作演算。
罗马数字 | I | V | X | L | C | D | M |
---|---|---|---|---|---|---|---|
数字 | 1 | 5 | 10 | 50 | 100 | 500 | 1000 |
- 重复数次:一个罗马数字重复几次,就表示这个数的几倍。
- 右加左减:
1. 在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。
2. 在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。
3. 左减的数字有限制,仅限于I
、X
、C
。比如45不可以写成VL
,只能是XLV
。
4. 但是,左减时不可跨越一个位值。比如,99不可以用IC
( 100-1)表示,而是用XCIX
([100-10]+[10-1])表示。(等同于阿拉伯数字每位数字分别表示。)
5. 左减数字必须为一位,比如8写成VIII
,而非IIX
。
6. 右加数字不可连续超过三位,比如14写成XIV,而非XIIII
。(见下方“数码限制”一项。)
- 加线乘千:
1. 在罗马数字的上方加上一条横线或者加上下标的Ⅿ
,表示将这个数乘以1000
,即是原数的1000
倍。
2. 同理,如果上方有两条横线,即是原数的1000000
(1000^2)
倍。
- 数码限制:
1. 同一数码最多只能连续出现三次,如40不可表示为XXXX
,而要表示为XL
。
2. 例外:由于IV是古罗马神话主神朱庇特(即IVPITER
,古罗马字母里没有J
和U
)的首字,因此有时用IIII
代替IV
。
思路
- 我们可以用两个变量保存当前数字和之前的数字就行了。
- 如果当前数字是最后一个数字,或者之后的数字比它小的话,则加上当前数字
- 其他情况则减去这个数字
这样思路做下去我觉得还是一种不是很麻烦的方法。
代码
nt romanToInt(char* s) {
int i = 0;
int sum = 0;
int size,temp,flag;
while (s[i] != '\0'){
i++;
}
size = i;
for(i = 0;i<size;i++){
switch (s[i]){
case 'I':temp = 1;
break;
case 'V':temp = 5;
break;
case 'X':temp = 10;
break;
case 'L':temp = 50;
break;
case 'C':temp = 100;
break;
case 'D':temp = 500;
break;
case 'M':temp = 1000;
break;
}
switch (s[i+1]){
case 'I':flag = 1;
break;
case 'V':flag = 5;
break;
case 'X':flag = 10;
break;
case 'L':flag = 50;
break;
case 'C':flag = 100;
break;
case 'D':flag = 500;
break;
case 'M':flag = 1000;
break;
}
if(i==size-1 || flag<=temp){
sum += temp;
}else{
sum -= temp;
}
}
return sum;
}
因为我用的是c语言,所以需要很多switch解决处理,但是如果说用java的话,可以使用map就简单很多了!