Leetcode刷题:整数转罗马数字

183 阅读3分钟

这是我参与新手入门的第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)。

总结

到此我们就完成了整数转罗马数字,现在我们来总结一下:

  1. 首先我们分析了罗马数字的组成规则,得到了13种对应关系
  2. 然后我们根据对应关系并尽可能用较大的数字字符来表示,并完成了编码工作
  3. 最后我们实现了整数转罗马数字的算法