这是我参与新手入门的第2篇文章。
题目描述
罗马数字包含以下七种字符: 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。 给你一个整数,将其转为罗马数字。
思路分析
由题目分析我们可以得到13种数字与字符的对应关系,分别是7种罗马字符和6种特殊规则字符,如下所示
字符 数值
M 1000
CM 900
D 500
CD 400
C 100
XC 90
L 50
XL 40
X 10
IX 9
V 5
IV 4
I 1
在罗马数字中小的数字在大的数字的右边,如此我们可以通过以上对应关系表示,例如
数字:1590
表示:MDXC
数字:380
表示:CCCLXXX
代码实现
由以上分析,我们可以实现如下代码
/**
* @param {number} num
* @return {string}
*/
const intToRoman = function (num) {
const numSymbols = [
[1000, 'M'],
[900, 'CM'],
[500, 'D'],
[400, 'CD'],
[100, 'C'],
[90, 'XC'],
[50, 'L'],
[40, 'XL'],
[10, 'X'],
[9, 'IX'],
[5, 'V'],
[4, 'IV'],
[1, 'I'],
]; //{1}
let roman = ''; //{2}
for (let i = 0; i < numSymbols.length; i++) {
const [v, r] = numSymbols[i]; //{3}
while (num >= v) { //{4}
num -= v; //{5}
roman += r; //{6}
}
}
return roman; //{7}
};
首先我们列出了数字与罗马字符的对应关系(1),接着我们定义了一个变量用来储存最后生成的罗马字符串 roman(2),然后我们循环这个对应关系的数组,将每次循环得到的值结构出来(3),判断 num 是否比当前循环到的对应关系大(4),如果大于当前的值,我们减少当前的值(5),并且将当前的符号拼接到roman的后面(6),重复这个过程(4、5、6)。最后返回得到的 roman(7)。
总结
到此我们就完成了整数转罗马数字,现在我们来总结一下:
- 首先我们分析了罗马数字的组成规则,得到了13种对应关系
- 然后我们根据对应关系并尽可能用较大的数字字符来表示,并完成了编码工作
- 最后我们实现了整数转罗马数字的算法