问题
罗马数字转整数#13
String#roman2Int
给 String
定义一个私有的扩展方法 roman2Int
:
1 2 3
| private fun String.roman2Int():Int{ }
|
单元测试
1 2 3 4 5 6 7 8
| @Test fun romanToInt() { assert("III".roman2Int() == 3) assert("IV".roman2Int() == 4) assert("IX".roman2Int() == 9) assert("LVIII".roman2Int() == 58) assert("MCMXCIV".roman2Int() == 1994) }
|
解法
由题目可以得出:
- 罗马数字由
I、V、X、L、C、D、M
构成
- 当小值在大值得左边,则减小值
- 当小值在大值的右边,则加小值
由以上结论可以得出,右值永远为正,最后一位必为正
码表:
key |
value |
I |
1 |
V |
5 |
X |
10 |
L |
50 |
C |
100 |
D |
500 |
M |
1000 |
代码实现小技巧,从第1位开始遍历,比较 cur
和 pre
的大小,从而确定是做加法还是减法,然后更新 pre 的值。只有最后一位时,做加法。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
private fun String.roman2Int(): Int {
val dictionary = hashMapOf( 'I' to 1, 'V' to 5, 'X' to 10, 'L' to 50, 'C' to 100, 'D' to 500, 'M' to 1000 )
var sum = 0
var prev: Int = dictionary[first()] ?: throw IllegalStateException()
for (index in 1 until length) {
val cur = dictionary[get(index)] ?: throw IllegalStateException()
when { cur > prev -> sum -= prev else -> sum += prev }
prev = cur }
sum += prev return sum }
|
参考