문제
코드
function solution(expression) {
function calculator(a, b, oper) {
if (oper === "+") return a + b;
if (oper === "*") return a * b;
if (oper === "-") return a - b;
}
const combinations = [
["+", "*", "-"],
["+", "-", "*"],
["*", "+", "-"],
["*", "-", "+"],
["-", "*", "+"],
["-", "+", "*"],
];
let answer = Number.MIN_SAFE_INTEGER;
combinations.forEach((combination) => {
const operands = expression.match(/[0-9]+/g).map(Number);
const operators = expression.match(/[\*\+\-]/g);
combination.forEach((c) => {
let idx = operators.indexOf(c);
while (idx !== -1) {
operands[idx] = calculator(operands[idx], operands[idx + 1], c);
operands.splice(idx + 1, 1);
operators.splice(idx, 1);
idx = operators.indexOf(c);
}
});
if (answer < Math.abs(operands[0])) answer = Math.abs(operands[0]);
});
return answer;
}
풀이
풀이 순서는 다음과 같다.
1. [+, *, -] 연산자의 우선순위를 반영한 6개 경우의 수를 배열로 만들어둔다.
(연산자의 개수가 2개 혹은 3개이므로 경우의 수를 함수로 만들어서 개수에 따라 달리할 수도 있지만
최대 경우의 수가 6개이므로 더 번거로운 일이라 생각했다.)
2. 각 경우에 대해서, 문자열 expression으로부터 연산자, 피연산자를 각각 배열에 분리해두고
연산자 우선순위를 고려해서 차례대로 연산을 해준다.
ex) +, *, - 순으로 우선순위가 있다면 연산자가 담긴 배열의 첫번째 인덱스부터 순차적으로 조회하면서
모든 + 연산을 처리하고, 다음으로 * 연산을 모두 처리하고, -의 연산을 모두 처리하면 된다.
연산자 배열 0번 인덱스에 있는 연산자를 처리할 때, 피연산자 배열 0,1번 인덱스에 있는 피연산자를 이용한다.
3. 각 경우의 우선순위를 고려한 최종 연산 결과를 가지고 절댓값을 취해주고 값이 최댓값이라면 최댓값을 갱신해준다.
4. 모든 경우의 수에 대해 1-3번 단계를 수행한 최댓값이 문제의 정답이다.
주석을 포함한 코드
function solution(expression) {
function calculator(a, b, oper) {
if (oper === "+") return a + b;
if (oper === "*") return a * b;
if (oper === "-") return a - b;
} // 문자열 형태의 연산자를 입력받아 해당 연산을 수행한다.
const combinations = [
["+", "*", "-"],
["+", "-", "*"],
["*", "+", "-"],
["*", "-", "+"],
["-", "*", "+"],
["-", "+", "*"],
]; // 6가지 경우의 수를 선언
let answer = Number.MIN_SAFE_INTEGER;
combinations.forEach((combination) => {
const operands = expression.match(/[0-9]+/g).map(Number); // operands에 피연산자를 담고 문자열을 숫자로 형변환
const operators = expression.match(/[\*\+\-]/g); // operators에 연산자를 담는다.
combination.forEach((c) => { // 모든 경우의 수에 대해 작업을 수행한다.
let idx = operators.indexOf(c);
while (idx !== -1) {
operands[idx] = calculator(operands[idx], operands[idx + 1], c);
operands.splice(idx + 1, 1);
operators.splice(idx, 1);
idx = operators.indexOf(c);
} // 더이상 operators 배열에 해당하는 연산자가 없을 때 까지 반복한다.
// 0번 인덱스에서 연산자가 발견되었을 때 피연산자 배열의 0,1번 피연산자로 계산을 한다.
// 피연산자 배열의 0번 인덱스에 연산 결과를 넣고, 연산자 0번 인덱스, 피연산자 1번 인덱스에 있는 원소를 제거한다.
// 작업이 끝나면 연산자 배열에 찾으려는 연산자가 더 존재하는지 검사하고 존재한다면 위의 작업을 반복수행한다.
});
// 마지막 연산은 피연산자의 0,1번 인덱스 + 연산자의 0번 인덱스가 사용되며 피연산자 인덱스 0번에 최종 연산 결과가 담긴다.
if (answer < Math.abs(operands[0])) answer = Math.abs(operands[0]); // 절댓값을 취해서 최댓값 갱신 여부를 판단한다.
});
return answer;
}
'DS & Algorithm > programmers' 카테고리의 다른 글
[프로그래머스] 거리두기 확인하기 (0) | 2021.12.16 |
---|---|
[프로그래머스] 2개 이하로 다른 비트 - 자바스크립트 (0) | 2021.06.30 |
[프로그래머스] 행렬 테두리 회전하기 - 자바스크립트 (0) | 2021.06.29 |
[프로그래머스] 프렌즈4블록 - 자바스크립트 (0) | 2021.06.29 |
[프로그래머스] 방금그곡 - 자바스크립트 (0) | 2021.06.28 |