Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
의 규칙으로 작성된 로마자 문자열을 정수로 변환하여 반환
단,IV = 4
IX = 9
XL = 40
XC = 90
CD = 400
CM = 900
이라는 예외가 있음
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
const symbols = {
'I' : 1,
'V' : 5,
'X' : 10,
'L' : 50,
'C' : 100,
'D' : 500,
'M' : 1000
};
let res = 0;
for (let i = 0; i < s.length; i++) {
const curr = symbols[s[i]];
const next = i + 1 < s.length ? symbols[s[i + 1]] : 0;
if (curr < next) {
res += (next - curr);
i++;
} else
res += curr;
}
return res;
};
기본 규칙을 저장해놓은 맵 symbols
문자열을 순회하면서 현재 인덱스가 가리키는 값과 다음 인덱스가 가리키는 값을 담아놓음
규칙 상 1000의 자리 -> 100의 자리 -> 10의 자리 순으로 표현되며, 작은 수보다 큰수가 먼저 나오는게 맞지만
두 글자를 합친 예외 규칙은 작은 수가 앞으로 가므로 curr < next 일때는 예외 값(뒷자리 수에서 앞자리 수 뺀 값)으로 계산
또한 뒷자리 수까지 계산에 넣었으므로 i++ 하여 한칸 더 뒤로 이동
이 외에는 curr 값 더하기
Accepted
Runtime 110ms (Beats 71.59%)
Memory 54.57MB (Beats 63.15%)
처음에는 그냥 무작정 case 문도 써보고 if를 잔뜩 넣어서 작성했었다. 근데 코드가 점점 길어질 수록 이건 아니다라는 생각이 들었고 솔루션을 참고한 결과 map 활용하기 + 큰 수부터 나열되므로 다음 문자가 큰 수면 예외 규칙임 + 예외 규칙은 뒷 자리에서 앞 자리 뺀 값임을 한번에 깨달을 수 있었다. 이게 참 easy 레벨의 문제라고 하지만 그럴 수록 더 어려운 것 같다. 처음에 그랬던 것처럼 노가다로 막 적을 수도 있고, 또 다른 방법이 무수하게 많기 때문에 얼마나 더 효율적으로 만드는지 실력을 판가름 할 수 있는게 easy 레벨인 것 같다.