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;
}