leetcode12:整数转罗马数字
马数字包含以下七种字符: I, V, X, L,C,D 和 M。
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-to-roman
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
描述
例如, 罗马数字 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
示例对应表
字符 | 数值 | 说明 |
---|---|---|
I | 1 | 基本组成原子 |
II | 2 | 1+1 |
III | 3 | 1+1+1 |
IV | 4 | 5-1 |
V | 5 | 基本组成原子 |
IX | 9 | 10-1 |
X | 10 | 基本组成原子 |
L | 50 | 基本组成原子 |
C | 100 | 基本组成原子 |
D | 500 | 基本组成原子 |
M | 1000 | 基本组成原子 |
问题分析
- 列出所有的基本组成原子(参考上表)
ATOM_MAP
- 将输出整数进行位数分解: 百、千、万等,注意十以及,十以下得先判断
- 分比对 1e5/1e5… 等进行取余,得到余数即可
- 结果存数组中
- 各种逻辑列举
- 1-9: fn1
- 10-99: fn2
- 100-999: fn3
- 1000-999: fn4
- 判断结果放进数组
- 数组转字符串输出
准备数据
var mapping = {
1: ["I", "V"],
2: ["X", "L"],
3: ["C", "D"],
4: ["M", "Z"],
};
1-9实现
// [1-9]
// I II III IV V VI VII VIII IX
function fn1(num) {
const map1 = mapping[1];
const map2 = mapping[2];
//1,5
if (num === 1) return map1[0];
if (num === 5) return map1[1];
//4,9
if (num == 4) return map1[0] + map1[1];
if (num == 9) return map1[0] + map2[0];
// 2,3
if (num <= 3) return map1[0].repeat(num);
// 6, 7, 8
if (num > 5) return map1[1] + fn1(num - 5);
}
10-99实现(只需要考虑10,90这种即可)
// [10, 99]
function fn2(num) {
const map2 = mapping[2];
const map3 = mapping[3];
if (num === 10) return map2[0];
if (num === 50) return map2[1];
//4,9
if (num == 40) return map2[0] + map2[1];
if (num == 90) return map2[0] + map3[0];
// 2,3
if (num <= 30) return map2[0].repeat(num / 10);
// 60, 70, 80
if (num > 50) return map2[1] + fn2(num - 50);
}
思考一下78的实现
// 78
console.log(fn2(70) + fn1(8));
重构 fn1/fn2,反思 fn3/fn4的实现
var mapping = {
0: ["I", "V"],
1: ["X", "L"],
2: ["C", "D"],
3: ["M", "Z"],
};
// [1-9]
// I II III IV V VI VII VIII IX
function fn(num, e) {
const map1 = mapping[0 + e];
const map2 = mapping[1 + e];
const plus = Math.pow(10, e);
//1,5
if (num === 1 * plus) return map1[0];
if (num === 5 * plus) return map1[1];
//4,9
if (num == 4 * plus) return map1[0] + map1[1];
if (num == 9 * plus) return map1[0] + map2[0];
// 2,3
if (num <= 3 * plus) return map1[0].repeat(num / (1 * plus));
// 6, 7, 8
if (num > 5 * plus) return map1[1] + fn(num - 5 * plus, e);
}
写一个实例
const fn1 = function (num) {
return fn(num, 0);
};
const fn2 = function (num) {
return fn(num, 1);
};
const fn3 = function (num) {
return fn(num, 2);
};
const fn4 = function (num) {
return fn(num, 3);
};
const res = fn4(1000) + fn3(900) + fn2(90) + fn1(4);
console.log(res); // MCMXCIV
数字分割部分
import ds from '@jswork/digits-split';
ds(1994);
// [1000, 900, 90, 4];