1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요. 로마 숫자를 숫자로 표기하면 다음과 같습니다. 로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다. III
= 3 XII
= 12 XXVII
= 27 입니다.
Symbol | Value |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
그런데 4를 표현할 때는 IIII
가 아니라 IV
입니다. 뒤의 숫자에서 앞의 숫자를 빼주면 됩니다. 9는 IX
입니다. I
는 V
와 X
앞에 와서 4, 9 X
는 L
, C
앞에 와서 40, 90 C
는 D
, M
앞에 와서 400, 900
VI
=6 이고,IV
=4 이기 때문에 처음에는 로마자의 순서에 따라I
가V
보다 나중에 나오면 더해주고, 먼저 나오면 빼주면된다고 생각했어요. 하지만 순서만으로는 비교할 수 없었어요.
그래서 알게된 방법은 로마자에 해당되는 숫자를 가지고 비교하는 것이었어요. 각 로마자를 모두 숫자로 바꾸어보는거죠.MMCMIV
는 숫자2904
와 같아요. 각 로마자마다 숫자로 바꾸어보면1000
,1000
,100
,1000
,1
,5
죠. 원래는 내림차순이 되어야하지만,100
,1000
그리고1
,5
와 같은 예외 케이스가 있어요. 이런 경우1000
에서100
을 빼주고,5
에서1
을 빼주는 것과 같이 큰 수에서 작은 수를 빼줘야 해요.
로마자를 숫자로 바꾸고 처음부터 차례대로 더해나가며 예외 케이스를 빼주면 최종적으로 로마자를 숫자로 바꾼 수를 알 수 있어요!
function romanToNum(s) {
let roman = {
I : 1,
V : 5,
X : 10,
L : 50,
C : 100,
D : 500,
M : 1000,
}
let saveNum = [];
let sum = 0;
for(let i = 0; i < s.length; i++){
for(num in roman){
if(s[i] === num){
saveNum.push(roman[num]) // 로마자에 해당되는 숫자를 saveNum배열에 담기
sum += roman[num] // 로마자에 해당되는 숫자 sum합에 더하기
}
}
if(saveNum[i-1] < saveNum[i]){ // 현재 담은 숫자가 이전 담은 숫자보다 크면
sum -= saveNum[i-1]*2; // sum합에서 이전 담은숫자*2만큼 빼기
}
}
return sum
}
- 로마자에 해당되는 숫자 저장
- 각 로마자에 해당되는 숫자를 객체의 형태로 저장해줍니다.
for...in
반복문으로 로마자에 해당되는 숫자 찾기
- 로마자에 해당되는 숫자를
saveNum
에 차례대로 넣어줍니다.- 로마자에 해당되는 숫자를
sum
에 차례대로 더해줍니다.
- 차례대로
saveNum
에 넣다가, 현재 담은 숫자가 이전 담은 숫자보다 크다면?
IV
와 같이 1, 5인 경우랍니다. 이럴 땐 현재 담은 숫자인 5에서 이전 담은 숫자인 1을 빼면되겠죠?- 근데 제 코드에선 로마자에 해당되는 숫자를
for...in
반복문에서sum
에 이미 더해준 상태이기 때문에 한 번이 아닌 두 번을 빼줘야 해요.IV
를 예시로 보자면, 저는for...in
의sum
에서 이미 1+5를 한 상태인거랍니다. 그래서 원래 나와야하는 숫자인 4가 되려면 1+5인 6에서 1을 2번 빼줘야 4가 나와요. 그래서 2번 빼주었답니다!
대단합니다....