Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 문자열
- toLowerCase()
- 공간 복잡도
- 너비 우선 탐색
- 연결 리스트
- 배열
- 거듭제곱
- 스택
- IS NOT NULL
- 백트래킹
- 브루트포스
- 정렬
- 시간 복잡도
- ifnull
- ListIterator
- 그래프 이론
- MySQL
- 수학
- 요세푸스 문제
- 그래프 탐색
- 정수론
- toUpperCase()
- 분할 정복
- 빅오 표기법
- BFS
- 자료 구조
- 큐
- 구현
- 그리디 알고리즘
- 소수 판정
Archives
- Today
- Total
배푸니까
[백준 / JAVA] 2504. 괄호의 값 본문
반응형
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. 어려운 로직..
- 명확하게 이해를 완전히 하고 해결한 문제는 아니다.
- 다른 사람들의 코드를 참고해서 최대한 이해를 해보려고 했지만, 나중에 다시 이해하는 시간을 가져야 할 것 같다.
반응형
'백준' 카테고리의 다른 글
[백준 / JAVA] 24444. 알고리즘 수업 - 너비 우선 탐색 1 (0) | 2023.08.01 |
---|---|
[백준 / JAVA] 10799. 쇠막대기 (0) | 2023.07.10 |
[백준 / JAVA] 2164. 카드2 (0) | 2023.06.30 |
[백준 / JAVA] 6198. 옥상 정원 꾸미기 (0) | 2023.06.30 |
[백준 / JAVA] 17298. 오큰수 (0) | 2023.06.30 |