题目
罗马数字包含以下七种字符: 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 <= num <= 3999
示例1
输入: num = 3
输出: “III”
示例2
输入: num = 4
输出: “IV”
示例3
输入: num = 9
输出: “IX”
示例4
输入: num = 58
输出: “LVIII”
解释: L = 50, V = 5, III = 3.
示例5
输入: num = 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.
解题分析一:按规则模拟拼接
做这道题,我们可以先不从程序的角度去分析,如果给你一张纸和一直笔,让你在纸上写出把13999之间的任意一个整数转换成罗马数字的整个过程你会怎么做?
首先我们会理清对应关系(不仅是基本关系,还有特殊罗马数字之间的关系)
基本盘
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
特殊盘
IV 4
IX 9
XL 40
XC 90
CD 400
CM 900
整理出了整数和罗马数字的关系,那么我们进行转换的话,无非就是比大小
一边比,一边拼,一边减
我们以 543 为例
543 >= 500 => D => 543 - 500 = 43
43 >= 40 => DXL => 43 - 40 = 3
3 >= 1 => DXLI => 3 - 1 = 2
2 >= 1 => DXLII => 2 - 1 = 1
1 >= 1 => DXLIII => 1 - 1 = 0 结束
按照这样的做题思路,我们完全可以把这些罗马数字和自己的整数之间的关系存储在容器当中,然后后目标整数进行比较。容器使用1个Dictionary或者2个List都可以,容器中从大到小存储对应关系,每次遍历比较即可。
解题一:按规则模拟拼接
解题分析二:硬编码数字
受到解法一的启发,我们可以将对应关系做的更加的极值,使用硬编码数字的形式来完成该题。所谓的硬编码数字,就是为每个数字设置一个编码的关系,类似“字符编码”中字符和二进制数字的对应关系,我们在这里设计一个不同位数字对应的罗马数字关系
由于题目中输入的数字是1到3999
那么我们可以为个、十、百、千位分别设置编码对应关系
那么有了这个自定义个硬编码数字关系,我们就可以算出整数的每一位然后进行拼接字符串即可,无非是需要使用一些容器存储每一位的编码关系
解题二:硬编码数组
总结
这道题不难,但是它的第二种解法可以帮助我们理解字符编码的概念
关于字符编码,你可以看看我的这篇文章
https://www.bilibili.com/read/cv16001311/
END