빡구현으로 하다가 너무 헷갈려서 다른 분의 풀이를 보다가 분배법칙
힌트를 얻어서 풀수 있었다.
(()[])
인 경우 2*(2+3) = 2*2 + 2*3
로 풀 수 있다.
초기에 ()
는 2[]
는 3으로 변경해준다면 (23)
으로 변경할 수 있다.(replaceAll
사용)
(
, [
인 경우 각 2,3을 뒤의 결과에 곱해준다.)
, ]
가 나오면 곱을 각 2,3을 제거해준다.(()[])
로 예를 들어보자면
이때 주의해야할 점은 올바른 괄호열이어야 한다는 점에서, 분기 반복문 전에 올바른 괄호열 여부를 먼저 확인하고 실행해주었다.
(()[[]])([])
로 예를 들면 아래와 같다.
자세한 구현은 코드에서 설명하겠다.
public class 괄호의값 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String operation = br.readLine();
Stack<Character> stack = new Stack<>();
int temp = 0;
int num = 0;
//올바른 코드 라면
if (isCorrect(operation)) {
//"()" = 2, "[]" = 2로 변경.
operation = operation.replaceAll("\\[\\]", "3");
operation = operation.replaceAll("\\(\\)", "2");
for (char c : operation.toCharArray()) {
//스택이 비어있을 때
if (stack.isEmpty()) {
//열린 괄호가 들어온다면 stack에 열린괄호를 넣어준다.
//올바른 괄호열을 확인했기때문에 비어있을때 닫힌 괄호는 들어오지 않는다.
if (c == '[' || c == '(') {
stack.push(c);
//각 괄호에 맞는 값을 곱해줄 값(temp)에 추가해준다.
//stack이 비어있는 경우 temp는 0이기 때문에 더해줘야한다.
if (c == '[')
temp += 3;
if (c == '(')
temp += 2;
} else {
//스택이 비어있을때 숫자가 들어온다면 temp는 0이므로 숫자만 결과값에 더해준다.
int number = Integer.parseInt(String.valueOf(c));
num += number;
}
} else {
//열기괄호
if (c == '[' || c == '(') {
stack.push(c);
//열기괄호인 경우 곱해줄 값(temp)에 각 값을 추가(곱)해준다.
if (c == '[')
temp *= 3;
else
temp *= 2;
}
//닫기 괄호
else if (c == ']' || c == ')') {
//']'
if (c == ']') {
//닫기 괄호시 3만 남게 되면 나눗셈 결과가 1이 나오기 때문에 뺴기로 제거
//그 이상의 값이 남게 된다면 나눗셈으로 temp값 갱신
if (temp / 3 == 1) {
temp -= 3;
} else {
temp /= 3;
}
}
//')'
//')' 닫기 괄호도 동일하다.
else {
if (temp / 2 == 1) {
temp -= 2;
} else {
temp /= 2;
}
}
stack.pop();
}
//숫자
else {
//괄호 안에서 숫자가 있을 시 temp의 값을 곱해서 결과값에 더해준다.
int number = Integer.parseInt(String.valueOf(c));
num += temp * number;
}
}
}
}
bw.write(String.valueOf(num));
bw.flush();
bw.close();
}
//올바른 코드 여부
static boolean isCorrect(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(' || c == '[') {
stack.push(c);
} else {
if (stack.isEmpty() || (c == ']' && stack.peek() != '[') || (c == ')' && stack.peek() != '(')) {
return false;
}
stack.pop();
}
}
if (!stack.isEmpty()) {
return false;
}
return true;
}
}
다른 분들의 코드에 비해 분기처리도 많고 예외케이스를 찾으면 구현한 거라 복잡하다, 나중에 시간내서 다른 분의 코드도 확인하고 최적화를 해야할것 같다.