本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
罗马数字包含以下七种字符: 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。 给你一个整数,将其转为罗马数字。
输入: num = 3
输出: "III"
解题思路
思路一
我们先枚举出可能出现的罗马数字,并表明每个罗马数字所代表的数值,然后对数组进行循环,从大到小的循环罗马数字,并判断传入的参数是否大于该值,如果大于,则减去这个数字并在结果,最后将罗马数字添加到尾部
var intToRoman = function (num) {
const valueSymbolArr = [[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']]
let result = ''
for(const [item,symbol] of valueSymbolArr){
while(num>=item){
result+=symbol
num-=item
}
if(num == 0) break
}
return result
};
思路二
我们首先要定义出各数字所对应的罗马数字字典,接着呢根据计算规则,我们可以知道,罗马数字字符串的拼接都是从大到小进行拼接的,就是是从“千到一”(M到I)进行拼接,所以,当我们获取到字典的keys,准备开始进行累加遍历的时候,需要对keys先进行反转,让其从大到小排列,最后开始进行遍历累减,每得到一个值,就退出当前遍历。
var intToRoman = function(num) {
if (!num) return "";
const NUMBER_DICT = {
1: 'I',
4: 'IV',
5: 'V',
9: 'IX',
10: 'X',
40: 'XL',
50: 'L',
90: 'XC',
100: 'C',
400: 'CD',
500: 'D',
900: 'CM',
1000: 'M'
};
let lastNum = num;
let romanStr = '';
let numbers = Object.keys(NUMBER_DICT);
numbers = numbers.map(i=>Number(i));
numbers.reverse();
while (lastNum > 0) {
let len = 0;
while (len < numbers.length) {
if (lastNum >= numbers[len]) {
lastNum-=numbers[len];
romanStr+=NUMBER_DICT[numbers[len]]
break;
}
len++;
}
}
return romanStr;
}
思路三
首先把特殊的值给直接返回,减少一下执行的时间,然后考虑每个位上的值,比如十位、百位、千位,如果都换算成个位数,再匹配对应的罗马数字,最后再替换一下各自对应的字符即可
var intToRoman = function (num) {
let a = 0, b = 0, c = 0, d = 0;
let str = ''
const obj = {
0: '',
1: 'I',
2: 'II',
3: 'III',
4: 'IV',
5: 'V',
6: 'VI',
7: 'VII',
8: 'VIII',
9: 'IX'
}
const quickMap = {
1: 'I',
5: 'V',
10: 'X',
50: 'L',
100: 'C',
500: 'D',
1000: 'M',
}
if (quickMap.hasOwnProperty(num)) {
return quickMap[num];
}
function getPrefix(n, val) {
return Math.floor(n / val);
}
if (num > 1000) {
a = getPrefix(num, 1000);
for (let i = 0; i < a; i++) {
str += 'M'
}
}
if (num > 100) {
b = getPrefix(num - a * 1000, 100);
str += obj[b].replaceAll('V', 'D').replaceAll('I', 'C').replaceAll('X', 'M');
}
if (num > 10) {
c = getPrefix(num - a * 1000 - b * 100, 10);
str += obj[c].replaceAll('V', 'L').replaceAll('X', 'C').replaceAll('I', 'X');
}
d = getPrefix(num - a * 1000 - b * 100 - c * 10, 1);
str += obj[d];
return str;
};