Q. 로마자에서 숫자로 바꾸기
- 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
처음 접근 법
function romanToNum(s) {
const symbolArr= ['I', 'V', 'X', 'L', 'C', 'D', 'M'];
const numValue = [1, 5, 10, 50, 100, 500, 1000];
const symbol = s.split('');
for (i = 0; i < symbolArr.length; i++){
symbolArr[i] = numValue[i]
}
}
romanToNum('XXVII')
1. 각 값을 배열로 만들어, 해당 index값을 기준으로 로마자에 값을 부여
2. 전달받은 '로마자'를 '로마자 배열(symbolArr)'에 매칭하여, 각 값을 더한 값을 반환
3. 4, 9, 40, 90, 400, 900의 예외 케이스 설정
처음엔 위와 같은 생각을로 접근했다.
그러나 2번부터 막힘🤯 (시간 초과)
A. 최종 답 (+네비게이터님의 피드백)
📍TIP
• 객체 사용
• ES6의 Spread Operator(스프레드 연산자)
function romanToNum(s) {
let obj = {
I:1,
V:5,
X:10,
L:50,
C:100,
D:500,
M:1000
}
const arr = [...s];
let sum = 0;
for(i = 0; i < arr.length; i++ ){
let a = obj[arr[i]]
let b = obj[arr[i+1]]
if(a < b){
sum -= a
}else{
sum = sum + a
}
}
return sum
}
romanToNum('XXVII') // 27
romanToNum('IX') // 9
romanToNum('XC') // 90
1. 객체(object) 사용
- 'a의 값은 x', 'b의 값은 y'...와 같은 형식의 조건은 key와 value값으로 묶어 객체로 사용하면 유용하다.
let obj = {
I:1,
V:5,
X:10,
L:50,
C:100,
D:500,
M:1000
}
2. 예외 규칙 찾기
- 일반 케이스와 예외 케이스의 차이를 생각하고, 예외 규칙 구하기
👉 일반 케이스
3은 III = 1 + 1 + 1
5는 V = 5
6은 VI = 5 + 1
60은 XL = 50 + 10
로마자로 기준 : 뒤의 수가 작은 수 ( 앞의 값 > 뒤의 값 )
아라비아 숫자 기준 : 앞의 수에 뒤의 수를 더함 ( 앞의 값 + 뒤의 값)
👉 예외 케이스
4는 IV = -1 + 5
9는 IX = -1 + 10
40은 XL = -10 + 50
90은 XC = -10 + 100
로마자로 기준 : 작은 수, 뒤의 수가 큰 수 ( 앞의 값 < 뒤의 값 )
아라비아 숫자 기준 : 뒤의 수에서 앞의 수를 뺌 (뒤의 값 - 앞의 값)
- if 문을 사용해 예외 케이스(앞의 값 < 뒤의 값)일 경우
뒤의 값에서 앞의 값을 빼는 연산 적용
const arr = [...s];
let sum = 0;
for(i = 0; i < arr.length; i++ ){
let a = obj[arr[i]]
let b = obj[arr[i+1]]
if(a < b){
sum -= a
}else{
sum = sum + a
}
}
❗️헷갈렸던 부분 확실히 알고 넘어가기
const arr = [...s];
let sum = 0;
for(i = 0; i < arr.length; i++ ){
let a = obj[arr[i]]
let b = obj[arr[i+1]]
if(a < b){
sum -= a
}
sum = sum + a
}
처음엔 sum = sum + a 를 기본으로 하고,
예외의 경우에만 sum -= a를 수행하게 위해 if 조건문만 작성했었다.
하지만 예외 케이스로 계산돼야 할 값이 일반 케이스로 연산된 값으로 출력됐다.
romanToNum('XXVII') // 27
romanToNum('IX') // 10 : 9가 나와야 함
romanToNum('XC') // 100 : 90이 나와야 함
console.log 폭풍 찍기⌨️
✔️ if을 잘못 활용했다.
예를 들어 IX값이 주어졌을 때,
if 조건을 만족한다. sum -= a실행.
즉, 10-1 = 9값이 나온다.
그런데 밑의 sum = sum + a도 실행 해버리면서
도로 1이 더해지는 것
10 - 1 = 9
9 + 1 = 10
A연산 or B연산이 되어야하는데, A연산 and B연산을 만들어 버린 것이다.
고로 이럴 땐 if else 문 또는 삼항연산자로 작성해줘야한다.
// if else 문
if(a < b){
sum -= a
}else{
sum = sum + a
}
// 삼항연산자
a < b ? sum -= a : sum = sum + a
확인하고 보니 당연한 문제였는데, 꼬아서 생각하다 돌아가버렸다.
3. Spread Operator(스프레드 연산자) MDN명세
const arr = 'abcdef';
console.log(arr.split('')); // [ 'a', 'b', 'c', 'd' ]
console.log([...arr]); // [ 'a', 'b', 'c', 'd' ]
console.log([...arr,'last']); // [ 'a', 'b', 'c', 'd', 'last' ]
console.log(['first',...arr]); // [ 'first', 'a', 'b', 'c', 'd' ]
반응형
'D.evelop [CS] > Algorithm' 카테고리의 다른 글
[Algorithm 011] JS - topK (0) | 2021.10.03 |
---|---|
[Algorithm 010] JS - moreThanHalf (0) | 2021.10.02 |
[Algorithm 008] JS - 1주차 test 다시 풀기 (0) | 2021.09.23 |
[Algorithm 007] JS - sameReverse (0) | 2021.09.16 |
[Algorithm 006] JS - reverse (0) | 2021.09.14 |
댓글