BOJ[2504] - 괄호의 값 by JavaScript
괄호의 값
문제
언어
- JavaScript
문제 풀이 step 1
- 우선 주어진 입력이 올바른 괄호열인지 아닌지 검사합니다.
- 저는 검사하는 동시에 올바른 괄호열인 경우 올바른 괄호열의 최소 단위만큼 각각 분리했습니다.
- 스택을 준비하고 여는 괄호가 들어올 경우 스택에 push 합니다.
- 올바른 괄호열이라면 닫는 괄호가 들어왔을 때 스택에 자신에 맞는 여는 괄호가 있습니다.
- 즉, 올바른 문자열이라면 ‘)’은 ‘(‘와 만나게 되고, ‘[‘은 ‘]’와 만나게 됩니다.
- 이 경우가 아니라면 올바른 괄호열이 아니므로 0 을 return 합니다.
문제 풀이 step 2
- 분리된 올바른 괄호열을 가지고 값을 계산합니다.
- 스택을 준비합니다. 위와 마찬가지로 여는 괄호가 들어올 경우 스택에 push 합니다.
- 닫는 괄호가 들어왔을 때
- 스택에 맨위의 값이 자신과 맞는 여는 괄호일 경우에는 숫자로 변환 후 다시 스택에 넣습니다.
- 이 경우는 ‘()’ 또는 ‘[]’인 경우입니다.
- 스택의 맨위의 값이 숫자라면 pop을 하면서 여는 괄호가 나올 떄까지 반복 후 pop 한 숫자들을 합합니다.
- 이 경우는 ‘(X)’ 또는 ‘[X]’ 또는 ‘(XY)’ 인 경우입니다.
- 반복을 하다 여는 괄호가 ‘(‘ 이면 합한 값에 2를 곱하고, ‘[’ 이면 합한 값에 3을 곱하고 다시 스택에 넣습니다.
- 스택에 맨위의 값이 자신과 맞는 여는 괄호일 경우에는 숫자로 변환 후 다시 스택에 넣습니다.
- 이를 반복하면 올바른 괄호열의 값을 구할 수 있습니다.
문제 풀이 step 3
- 저는 각 올바른 괄호열을 분리해서 값을 계산했기 때문에 구한 값들을 모두 더하고 return 해줍니다.
소스 코드
const input = require("fs").readFileSync("/dev/stdin").toString().split("\n");
// 올바른 문자열인지 체크 및 여러개의 올바른 문자열을 각각 분리
const checkAndSplit = (input) => {
let check = true;
const splitedArr = [];
const stack = [];
let before = 0;
for (let i = 0; i < input.length; i++) {
if (input[i] === "(") {
stack.push("(");
} else if (input[i] === "[") {
stack.push("[");
} else if (input[i] === ")") {
if (stack[stack.length - 1] !== "(") {
check = false;
break;
}
stack.pop();
} else if (input[i] === "]") {
if (stack[stack.length - 1] !== "[") {
check = false;
break;
}
stack.pop();
}
if (stack.length === 0) {
splitedArr.push(input.substring(before, i + 1));
before = i + 1;
}
}
return [check, splitedArr];
};
// 각각 올바른 문자열에 대해서 괄호값 계산
const calculator = (input) => {
const stack = [];
for (let i = 0; i < input.length; i++) {
if (input[i] === "(" || input[i] === "[") {
stack.push(input[i]);
} else if (input[i] === ")" || input[i] === "]") {
const top = stack[stack.length - 1];
if (top === "(") {
stack.pop();
stack.push(2);
} else if (top === "[") {
stack.pop();
stack.push(3);
} else if (typeof top === "number") {
const numbers = [];
while (typeof stack[stack.length - 1] === "number") {
numbers.push(stack.pop());
}
const sum = numbers.reduce((ac, v) => ac + v, 0);
if (stack[stack.length - 1] === "(") {
stack.pop();
stack.push(sum * 2);
} else if (stack[stack.length - 1] === "[") {
stack.pop();
stack.push(sum * 3);
}
}
}
}
return stack[0];
};
const solution = (input) => {
const [check, splitedArr] = checkAndSplit(input[0]);
if (check === false) return 0;
const resArr = splitedArr.map((v) => calculator(v));
return resArr.reduce((ac, v) => ac + v, 0);
};
console.log(solution(input));