result
를 갱신하는 방법괄호를 열 때는 unit
을 곱하고, 괄호를 닫을 때는 result
에 값을 반영하는 방식으로 구현했다.
import java.io.*;
import java.util.Stack;
public class Main {
private static BufferedReader br;
private static BufferedWriter bw;
public static void main(String[] args) throws IOException {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = br.readLine();
int answer = calcValue(line);
bw.append(Integer.toString(answer));
br.close();
bw.close();
}
private static int calcValue(String line) {
Stack<Character> stack = new Stack<>();
int result = 0;
int subValue = 1;
for (int i = 0; i < line.length(); i++) {
char current = line.charAt(i);
switch (current) {
case '(':
stack.push(current);
subValue *= 2;
break;
case '[':
stack.push(current);
subValue *= 3;
break;
case ')':
if (isInvalid(stack, current)) return 0;
if (line.charAt(i - 1) == '(') result += subValue;
stack.pop();
subValue /= 2;
break;
case ']':
if (isInvalid(stack, current)) return 0;
if (line.charAt(i - 1) == '[') result += subValue;
stack.pop();
subValue /= 3;
break;
}
}
if (!stack.isEmpty()) return 0;
return result;
}
private static boolean isInvalid(Stack<Character> stack, char current) {
if (stack.isEmpty()) return true;
if (current == ')' && stack.peek() != '(') return true;
if (current == ']' && stack.peek() != '[') return true;
return false;
}
}
subValue
를 같이 쌓는 방법처음에 봤을 땐 이게 더 이해하기 어렵게 느껴졌는데 직접 처음부터 구현해보니까 이게 더 쉬운 것 같다.
괄호를 subValue
랑 같이 쌓는데, subValue
를 쌓는 타이밍은 괄호를 닫는 시점이다. 닫으면서 그 괄호 사이에 있는 값들을 다 더하고, unit(current)
를 곱해서 다시 stack
에 쌓는 것이다.
코드를 완성하고 제출하면서 오류가 총 2번 났는데, 이유는 아래와 같다.
1. 맨 마지막에 getResultValue()
없이 getSubValue()
로 결괏값을 계산했을 때, 꺼낸 값들 아래에 괄호와 값이 또 남아있을 수 있다. 이런 경우 0
을 리턴해야 한다. 따라서 새로운 메서드를 만들어서 결괏값이 유효한지 stack
을 다시 체크하도록 했다.
2. pair()
에서 리턴하는 괄호를 잘못 입력했다. 그냥 단순한 char 하나 오타였는데도 찾는데 2분이나 걸렸다. 역시 상수를 적극 활용하는 게 효과적이라는 것을 체감할 수 있었다.
import java.io.*;
import java.util.Stack;
public class Main {
private static BufferedReader br;
private static BufferedWriter bw;
public static void main(String[] args) throws IOException {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = br.readLine();
int answer = calcValue(line);
bw.append(Integer.toString(answer));
br.close();
bw.close();
}
private static int calcValue(String line) {
Stack<String> stack = new Stack<>();
for (int i = 0; i < line.length(); i++) {
char current = line.charAt(i);
if (isOpeningParentheses(current)) {
stack.push(current + "");
} else if (isClosingParentheses(current)) {
int subValue = Math.max(getSubValue(stack), 1);
if (stack.isEmpty() || !stack.pop().equals(pair(current))) return 0;
stack.push(subValue * unit(current) + "");
}
}
return getResultValue(stack);
}
private static boolean isOpeningParentheses(char current) {
return current == '(' || current == '[';
}
private static boolean isClosingParentheses(char current) {
return current == ')' || current == ']';
}
private static int getSubValue(Stack<String> stack) {
int result = 0;
while (!stack.isEmpty() && isNumber(stack.peek()))
result += Integer.parseInt(stack.pop());
return result;
}
private static boolean isNumber(String str) {
return !str.equals("(") && !str.equals(")")
&& !str.equals("[") && !str.equals("]");
}
private static String pair(char current) {
if (current == ')') return "(";
else return "[";
}
private static int unit(char current) {
if (current == ')') return 2;
else return 3;
}
private static int getResultValue(Stack<String> stack) {
int result = 0;
while (!stack.isEmpty()) {
String current = stack.pop();
if (!isNumber(current)) return 0;
else result += Integer.parseInt(current);
}
return result;
}
}