roman-to-integer#13

问题

罗马数字转整数#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位开始遍历,比较 curpre 的大小,从而确定是做加法还是减法,然后更新 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
}

参考