先来题干:
罗马数字包含以下七种字符: 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。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
示例 1:
输入: "III"
输出: 3
示例 2:
输入: "IV"
输出: 4
示例 3:
输入: "IX"
输出: 9
示例 4:
输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
先来一下博主的解答:
<script>
const obj = {
'III': 3,
'II': 2,
'IV': 4,
'IX': 9,
'XL': 40,
'XC': 90,
'CD': 400,
'CM': 900,
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000
}
let str = "MCMXCIV";
let number = 0;
for (var p in obj) {
//console.log(p); // 取得是key值
//console.log(obj[p]); //取得是value值
if (str.indexOf(p) != -1) {
// console.log(str.indexOf(p))
// console.log(p.length)
//str = str.slice(str.indexOf(p), str.indexOf(p) + p.length);
str = str.split(p).join("");
//console.log(str);
number += +obj[p];
}
}
//console.log(str)
console.log(number)
</script>
博主踩过的坑:
1、我想弄成map结构,但是我不知道他的key值,在map的查询里,是使用has方法,所以我还是使用了对象。
2、之前弄的数组,但是遍历的时候,仍然不知道key值,只知道value值,arr[i],所以数组不考虑。
3、只有对象,通过for in循环,才能拿到key值。
4、str.slice(str.indexOf(p), str.indexOf(p) + p.length);这句话意思是,我循环获取到key值,判断有没有key值,如果有,那么获取key值在字符串的起始下标,和起始下标+key值的长度,用slice方法截取,但是是返回截取的部分,而不是截取剩下的部分,于是还是用split了。
未来与展望:
这个算法,虽然成功了,但是还会有坑,碰到那种有重复的,就实现不了,不过我也不知道罗马数字,有没有重复的。