로마자에서 숫자로 바꾸기
1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요.
로마 숫자를 숫자로 표기하면 다음과 같습니다.
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다.
III = 3
XII = 12
XXVII = 27
입니다.
그런데 4를 표현할 때는 IIII가 아니라 IV 입니다.
뒤의 숫자에서 앞의 숫자를 빼주면 됩니다.
9는 IX입니다.
I는 V와 X앞에 와서 4, 9
X는 L, C앞에 와서 40, 90
C는 D, M앞에 와서 400, 900
알고리즘 문제는 항상 나한테 너무 어렵다.. 오늘도 구글링...
먼저 아래에는 reduce 메서드가 적용되었다.
이 게시물을 쓰기전에 reduce 메서드의 개념과 예시를 이곳에 정리해 두었다.
function romanToNum(s) {
const romanTable = {
I : 1,
V : 5,
X : 10,
L : 50,
C : 100,
D : 500,
M : 1000,
}
const arr = s.split('');
return arr.reduce((acc, item, index) => {
const currentValue = romanTable[item];
const nextValue = romanTable[arr[index + 1]];
if (nextValue > currentValue) {
acc -= currentValue;
} else {
acc += currentValue;
}
return acc;
}, 0);
}
console.log(romanToNum("XII")); // 12
console.log(romanToNum("XXVII")); // 27
console.log(romanToNum("XL")); // 40
console.log(romanToNum("XC")); // 90
먼저 문제에서 로마자를 더하거나 뺀다는 설명이 있으므로 if, else 문을 생각해볼 수 있다.
또 예시를 통해 로마자 중 뒤의 값이 앞의 값보다 클 때는 뺀다는 것을 유추해 볼 수 있다.
그럼 로마자에서 뒤의 값이 앞의 값보다 클 때는 두 개의 값을 비교해서 빼줘야 한다는 것을 알 수 있다.
그런데 XXVII 가 27로 출력되려면 10 + 10 + 5 + 1 + 1 , 이런식으로 값을 다 더해줘야 한다는 것도
알 수 있다.
함수를 실행할 때 받는 string 인자를 split 메서드를 사용해서 문자 하나하나를 배열 요소로 만듦.
그럼 위에서 이 문제에서 써야 할 숫자들을 미리 객체의 key, value 형태로 변수에 담아놓았으니 활용 가능.
reduce 메서드를 사용하여 조건마다 값을 더해주거나 빼준 다음 그 값을 리턴하도록 설정하는 함수 만들기.
그러면 이제 위 코드를 해석해 보겠다. ( 다른 쪽에 문제 + 코드 띄워 놓고 보는게 편함 )
arr이라는 변수에 s라는 인자를 받아 split 메서드를 사용
(ex: s = XXVII 는 [ 'X', 'X', 'V', 'I', 'I' ] 의 형태가 됨)
acc 의 초기 값은 0, item = 'X' 즉, item = 10, index = 0 인 상태에서 시작.
currentValue = romanTable['X'] = 10
nextValue = romanTable[현재 배열[0 + 1]] = romanTable['X'] = 10
조건문에서 else의 경우에 해당하므로 acc = 0 에 currentValue = 10 을 더하면 acc = 10
다시 돌아와서 currentValue = romanTable['X'] = 10
nextValue = romanTable[현재 배열[1 + 1]] = romanTable['X'] = 10
currentValue 10, nextValue 10 은 조건문의 else에 해당되므로
acc는 기존 acc 10 + currentValue 10 = 20이 된다.
다시 돌아와서 currentValue = romanTable['V'] = 5
nextValue = romanTable[현재 배열[2 + 1]] = romanTable['I'] = 1
currentValue 5, nextValue 1 은 조건문의 else에 해당되므로
acc는 기존 acc 20 + currentValue 5 = 25가 된다.
다시 돌아와서 currentValue = romanTable['I'] = 1
nextValue = romanTable[현재 배열[3 + 1]] = romanTable['I'] = 1
currentValue 1, nextValue 1 은 조건문의 else에 해당되므로
acc는 기존 acc 25 + currentValue 1 = 26이 된다.
다시 돌아와서 currentValue = romanTable['I'] = 1
nextValue = romanTable[현재 배열[4 + 1]] = romanTable[undefined] = 값 없음.
currentValue 1, nextValue '값 없음' 은 조건문의 else에 해당되므로
acc는 기존 acc 26 + currentValue 1 = 27이 된다.
작성하면서도 많이 헷갈렸다.. 일단 나중을 위해 기록해두었음!