C语言-罗马数字转整数-最详细的讲解

罗马数字包含以下七种字符: IVXLCDM

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II27 写做 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 ....

   

②从以上信息可知,构成罗马数字的就是 IVXLCDM这六个字符,此时就要搞懂罗马数字的构成规则了,比如:

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

这种方法是按照题目一步一步分析然后编码的,相对比较好理解,但是代码不够精简,后面会参考其他友友的解法,出一版解析的哦~

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

像太阳啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值