罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2
写做 II
,即为两个并列的 1 。12
写做 XII
,即为 X
+ II
。 27
写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
-
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。 -
X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。 -
C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。
示例 1:
输入: s = "III"
输出: 3
示例 2:
输入: s = "IV"
输出: 4
示例 3:
输入: s = "IX"
输出: 9
示例 4:
输入: s = "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: s = "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
重点来啦!分析题目:
①首先,根据题目明白罗马数字表示和阿拉伯数字表示的对应规则,描述如下:
1->I 2->II 3->III 4->IV 5->V 6->VI 7->VII 8->VIII 9->IX 10->X
11->XI 12->XII 13->XIII 14->XIV....
21->XXI:一个X表示一个10,即:10+10+1 ....
②从以上信息可知,构成罗马数字的就是 I
, V
, X
, L
,C
,D
和 M
这六个字符,此时就要搞懂罗马数字的构成规则了,比如:
*M表示1000,几个M相连出现就表示几千
MM:2000 即1000+1000
MMM:3000 即1000+1000+1000
*C表示100,D表示500
100~300由对应个数的C表示
C:100
CC:100+100
CCC:100+100+100
600~800的表示规则:
600:DC 即500+100
700:DCC 即500+100+100
800:DCCC 即500+100+100+100
400和900的表示规则比较特殊:
400表示成CD:右面的500-左面的100
900表示成CM:右面的1000-左面的100
*X表示10,L表示50
10~30:由对应的X表示
40的表示规则和400相同
60~80的表示规则和600~800相同
90的表示规则和900相同
看完百位上的对应规则,我相信这里读者可以自行表示了
换一种表述方式:
罗马数字的表示规则是:用几种已知的数字表示符号进行组合,然后用加法来计算
例如:表示1999
千位上的1000:M
百位上的900:CM (800怎么表示?DCCC)
十位上的90:XC (80怎么表示?LXXX)
个位上的9:Ix (8怎么表示?VIII)
规则描述:若表示的不是以上六种特殊情况,有如下规则:
个位:a<4(用I相加来表示) 5<a<9(用V和I来组合)
十位:a<40(用X相加来表示) 50<a<90(用L和X来组合)
百位:a<400(用C相加来表示) 500<a<900(用D和C来组合)
③了解了罗马数字的表示规则,以及题6种特殊规则,编码的思路就有了:
(1)数组指针s中的字符串构成了一个数字,先判断字符数组的大小:这里不能用sizeof(),用这个关键字操作数组时,返回的是数组的总字节大小,例如: char a[50]; a[0]='1'; a[1]='2'; printf("%d",sizeof(a)); 此时的输出结果是:50因为定义的数组长度的50 用的是strlen()函数:strlen()函数的作用就是计算一个字符串的长度 注:用这个函数需要引入:#include <string.h> (2)定义一个int型变量result,记录最终对应的阿拉伯数字是多少,并且要给result赋初值为0 (3)使用for循环对字符串进行遍历,并对每个字符对应的情况进行讨论: ①遍历第一个字符时: ①若碰到I,先判断I后面的字符是否为V或X ①若构成组合:IV 4 result+4 注意此时已经用了两个字符了,计数的i要进行++;本次循环结束 ②若构成组合:IX 9 result+9 同上 ③若不是,则对连续的I的个数进行计数 更新result,continue; 备注:个位数才会碰到I ②若碰到X,判断后面的字符是否为C或L ①若构成组合:XC 40 result+40 注意此时已经用了两个字符了,技术的i要进行++;本次循环结束 ②若构成组合:XL 90 result+90 同上 ③若不是,则对连续的X的个数进行计数 更新result,continue; ③若碰到C,判断后面的字符是否为D或M ①若构成组合:CD 400 result+400 注意此时已经用了两个字符了,技术的i要进行++;本次循环结束 ②若构成组合:CM 900 result+900 同上 ③若不是,则对连续的C的个数进行计数 更新result,continue; 接下来是最后一种没有考虑的情况: ④若碰到M,则result+1000;结束本次循环 ②第二次遍历过程同①
编码:
int romanToInt(char* s) {
int length = strlen(s);
int i,j,result=0;
for(i=0;i<length;i++)
{
if(s[i]=='C')
{
if(s[i+1]=='M')
{
result=result+900;
i++;
continue;
}else if(s[i+1]=='D')
{
result=result+400;
i++;
continue;
}else{
result=result+100;
continue;
}
}else if(s[i]=='X')
{
if(s[i+1]=='L')
{
result=result+40;
i++;
continue;
}else if(s[i+1]=='C')
{
result=result+90;
i++;
continue;
}else{
result=result+10;
continue;
}
}else if(s[i]=='I')
{
if(s[i+1]=='V')
{
result=result+4;
i++;
continue;
}else if(s[i+1]=='X')
{
result=result+9;
i++;
continue;
}else{
result=result+1;
continue;
}
}else if(s[i]=='V')
{
result=result+5;
}else if(s[i]=='L')
{
result=result+50;
}else if(s[i]=='D')
{
result=result+500;
}else if(s[i]=='M')
{
result=result+1000;
}
}
return result;
}
这种方法是按照题目一步一步分析然后编码的,相对比较好理解,但是代码不够精简,后面会参考其他友友的解法,出一版解析的哦~