题目描述如下:
首先看到题目后寻找规律:
- 值为4或9的10的整数倍的情况为第一种特殊情况, 先写出第一个辅助函数
function isSpecial(num: number) {
//只考虑 为10 的整数倍
if ((num > 10 && num % 10)) return false;
while (num > 10) {
num /= 10;
}
if (10 - num === 1 || 5 - num === 1) return true;
return false;
}
- 与当前位数的5的关系(个位数与5, 十位数与50)
大致思路: 将数字转化为数组形式, 然后通过循环来处理数据
写出第二个辅助函数, 得到转化后的数组 1234 => [4, 3, 2, 1]:
function getNumberArr(num: number) {
if (!num) return [0];
const res: number[] = [];
while (num) {
res.push(num % 10);
num = parseInt((num / 10).toString());
}
return res;
}
最终函数:
function intToRoman(num: number): string {
// 题目限制 1 <= num <= 3999
let res = '';
if (num < 1 || num > 3999) return res;
//拿到数组形式的数据 expect(getNumberArr(1234)).toEqual([4, 3, 2, 1]);
const nums = getNumberArr(num);
let p = '';
let q = '';
let z = '';
nums.forEach((item, index) => {
if (!item) return;
switch (index) {
//个位数下的情况
case 0:
p = 'I';
q = 'V';
z = 'X';
break;
//十位数下的情况
case 1:
p = 'X';
q = 'L';
z = 'C';
break;
//百位位数下的情况
case 2:
p = 'C';
q = 'D';
z = 'M';
break;
case 3:
//千位数下的情况
p = 'M';
q = '';
break;
default: break;
}
//计算倍数
let multiple = 1;
while (index > 0 && index--) {
multiple * 10;
}
//计算当前的值 1234 对应的四次值 为 4, 30, 200, 1000
const current = item * multiple;
//如果是 4 或 9 的情况
//if (isSpecial(current)) {
// if (current % 4) {
// //为 9, 按照要求拼接字符串
// res = `${p}${z}${res}`;
// } else {
// //为4
// res = `${p}${q}${res}`;
// }
// }
//后知后觉。优化---
if(item === 4){
res = `${p}${q}${res}`;
}else if(item === 9){
res = `${p}${z}${res}`;
}
else if (item === 5) {
//为 5
res = `${q}${res}`;
} else if (item < 5) {
//小与 5
while (item--) {
res = `${p}${res}`;
}
} else {
//大与 5, 取出减去 5的余数, 然后拼接
let tmp = item - 5;
while (tmp--) {
res = `${p}${res}`;
}
res = q + res;
}
});
return res;
}