백준
[백준 / JAVA] 2504. 괄호의 값
baefrica
2023. 7. 10. 19:05
반응형
https://www.acmicpc.net/problem/2504
2504번: 괄호의 값
4개의 기호 ‘(’, ‘)’, ‘[’, ‘]’를 이용해서 만들어지는 괄호열 중에서 올바른 괄호열이란 다음과 같이 정의된다. 한 쌍의 괄호로만 이루어진 ‘()’와 ‘[]’는 올바른 괄호열이다. 만일 X
www.acmicpc.net
💻 풀이 결과
💯 최종 코드
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
Stack<Character> stack = new Stack<>();
boolean isError = false;
// 중간중간에 저장될 숫자
int num = 1;
// 최종 답
int res = 0;
Loop: for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
switch (c) {
case '(':
stack.push(c);
// 괄호의 시작이므로
num *= 2;
break;
case '[':
stack.push(c);
// 괄호의 시작이므로
num *= 3;
break;
case ')':
// 올바르지 못한 괄호열인 경우
if (stack.isEmpty() || stack.peek() != '(') {
isError = true;
break Loop;
}
// 쌍을 이루는 괄호를 제거
stack.pop();
// 이전 괄호를 확인하고 최종 결과값에 더해준다.
if (str.charAt(i - 1) == '(') {
res += num;
}
// 다시 num 값을 2로 나눠준다.
num /= 2;
break;
case ']':
// 올바르지 못한 괄호열인 경우
if (stack.isEmpty() || stack.peek() != '[') {
isError = true;
break Loop;
}
// 쌍을 이루는 괄호를 제거
stack.pop();
// 이전 괄호를 확인하고 최종 결과값에 더해준다.
if (str.charAt(i - 1) == '[') {
res += num;
}
// 다시 num 값을 3으로 나눠준다.
num /= 3;
break;
}
}
// 마지막에 스택이 비었는지 확인을 해야한다!!
if (!stack.isEmpty()) {
isError = true;
}
// 출력
if (isError) {
System.out.println(0);
} else {
System.out.println(res);
}
}
}
💢 틀린 이유
- 메인 스택 1개와 서브 스택 2개를 만들어서 소괄호 사이에 있는지 대괄호 사이에 있는지 판별하려고 했다.
- 괄호 안에서 저장된 숫자가 있고 또 새로 2나 3으로 시작되는 경우의 예외가 있었다. 이 부분을 틀린 코드에서 해결하지 못했다.
틀린 풀이 과정
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
Stack<Character> mainStack = new Stack<>();
Stack<Integer> sub1 = new Stack<>(); // 소괄호 사이에 담기는 숫자 저장
Stack<Integer> sub2 = new Stack<>(); // 대괄호 사이에 담기는 숫자 저장
boolean isError = false;
int res = 0;
int num;
Loop: for (char c : str.toCharArray()) {
switch (c) {
case '(':
case '[':
mainStack.push(c);
break;
case ')':
// 올바르지 못한 괄호열인 경우
if (mainStack.isEmpty() || mainStack.peek() != '(') {
isError = true;
break Loop;
}
// 쌍을 이루는 괄호를 제거
mainStack.pop();
// 저장할 숫자 처리
num = 0;
// 소괄호 스택에 저장된 값이 없다면 그냥 2
if (sub1.isEmpty()) {
num = 2;
}
// 저장된 값이 있다면 그 값을 빼내서 곱하기 2
else {
num = (sub1.pop() * 2);
}
// pop하고 난 후, main스택이 비었으면
// 최종 결과값에 더해준다.
if (mainStack.isEmpty()) {
res += num;
}
// main스택의 top을 확인한다.
// top에 따라 어떤 스택에 저장할 지 달라진다.
else {
// 이미 저장되어 있는 값이 있다면 num에 더해준다.
if (mainStack.peek() == '(') {
while (!sub1.isEmpty()) {
num += sub1.pop();
}
sub1.push(num);
} else {
while (!sub2.isEmpty()) {
num += sub2.pop();
}
sub2.push(num);
}
}
break;
case ']':
// 올바르지 못한 괄호열인 경우
if (mainStack.isEmpty() || mainStack.peek() != '[') {
isError = true;
break Loop;
}
// 쌍을 이루는 괄호를 제거
mainStack.pop();
// 저장할 숫자 처리
num = 0;
// 대괄호 스택에 저장된 값이 없다면 그냥 3
if (sub2.isEmpty()) {
num = 3;
}
// 저장된 값이 있다면 그 값을 빼내서 곱하기 3
else {
num = (sub2.pop() * 3);
}
// pop하고 난 후, main스택이 비었으면
// 최종 결과값에 더해준다.
if (mainStack.isEmpty()) {
res += num;
}
// main스택의 top을 확인한다.
// top에 따라 어떤 스택에 저장할 지 달라진다.
else {
// 이미 저장되어 있는 값이 있다면 num에 더해준다.
if (mainStack.peek() == '[') {
while (!sub2.isEmpty()) {
num += sub2.pop();
}
sub2.push(num);
} else {
while (!sub1.isEmpty()) {
num += sub1.pop();
}
sub1.push(num);
}
}
break;
}
}
// *** 마지막에 스택이 비었는지 확인을 해야한다!! ***
if (!mainStack.isEmpty()) {
isError = true;
}
// 출력
if (isError) {
System.out.println(0);
} else {
System.out.println(res);
}
}
}
💬 풀이 과정
- 소괄호 사이에 있으면 2를 곱해주고, 대괄호 사이에 있으면 3을 곱해주는 단순 계산 방식이 활용되었다.
- num에 현재 숫자 값을 저장해 주고 계속해서 괄호가 닫히면 다시 2로 나눠주거나 3으로 나눠주는 방식이다.
💡 깨달은 점
1. 어려운 로직..
- 명확하게 이해를 완전히 하고 해결한 문제는 아니다.
- 다른 사람들의 코드를 참고해서 최대한 이해를 해보려고 했지만, 나중에 다시 이해하는 시간을 가져야 할 것 같다.
반응형