🔺 문제
2800번: 괄호 제거
첫째 줄에 음이 아닌 정수로 이루어진 수식이 주어진다. 이 수식은 괄호가 올바르게 쳐져있다. 숫자, '+', '*', '-', '/', '(', ')'로만 이루어져 있다. 수식의 길이는 최대 200이고, 괄호 쌍은 적어도 1개
www.acmicpc.net
🧩 해결 아이디어
• 문자열 + 스택 + 재귀
- 필요 자료구조
- (여는 괄호 위치, 닫는 괄호 위치) 저장 객체
- 괄호 위치 객체 저장 리스트
- 괄호 제거해서 나오는 식 저장할 TreeSet
- 괄호 지울지 말지 판단용 boolean 배열
- 여는 괄호인 경우, 스택에 시작 위치 인덱스를 넣는다.
- 닫는 괄호인 경우, (스택의 여는 괄호 인덱스, 현재 인덱스)를 넣는다.
- 재귀를 통해 괄호를 표시할지 말지 각 쌍들을 조합하여 만들 수 있는 모든 경우의 수를 구한다. (백트래킹)
- 결과는 TreeSet에 저장하여 중복을 없애고, 자동으로 사전 순 정렬하게 한다.
💥 유의사항
재귀를 돌려도 크기가 2^10이라 괜찮다.
🔺 코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
import java.util.*;
import java.io.*;
public class Main {
static char[] ch;
static List<Pair> list = new ArrayList<>();
static Set<String> result = new TreeSet<>();
static boolean[] check; // 괄호 지울지 말지 판단하는 배열
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
ch = br.readLine().toCharArray();
// 1. 괄호 쌍 구하기
Stack<Integer> stack = new Stack<>();
for(int i = 0 ; i < ch.length ; i++) {
if(ch[i] == '(') {
stack.push(i);
}
else if(ch[i] == ')') {
list.add(new Pair(stack.pop(), i));
}
}
// 2. 괄호 존재하는 모든 조합 구하기
check = new boolean[ch.length];
comb(0);
// 출력하기
Iterator<String> iter = result.iterator(); // set을 iterator 안에 담기
while(iter.hasNext()) {
System.out.println(iter.next());
}
}
private static void comb(int depth) {
if(depth == list.size()) {
boolean b = false; // 괄호가 1개 이상 제거되었는지 나타내는 변수
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < ch.length ; i++) {
if(!check[i]) {
sb.append(ch[i]);
}
else {
b = true;
}
}
if(b) { // 최소 1개의 괄호가 제거된 경우, 결과 set에 저장
result.add(sb.toString());
}
return;
}
// 현재 괄호 제거 안 함
comb(depth + 1);
// 현재 괄호 제거
Pair now = list.get(depth);
check[now.start] = true;
check[now.end] = true;
comb(depth + 1);
check[now.start] = false;
check[now.end] = false;
}
}
class Pair {
int start, end;
public Pair(int start, int end) {
this.start = start;
this.end = end;
}
}
|
cs |
🔺 다른 풀이들
- 좀 깔끔해보여서! 나중에 읽기
괄호제거-2800번(java)
https://www.acmicpc.net/problem/2800 2800번: 괄호 제거 첫째 줄에 음이 아닌 정수로 이루어진 수식이 주어진다. 이 수식은 괄호가 올바르게 쳐져있다. 숫자, '+', '*', '-', '/', '(', ')'로만 이루어져 있다. 수식
spacefordeveloper.tistory.com
💬 느낀 점
쌍 사용할지 말지 구할 때 재귀 써야하는거 아니야? 했는데 진짜 재귀를 쓰는 것이었다고 한다.
비슷한 문제 보면서 감을 좀 익혀야겠다.....ㅠ
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V | 12.24 | 240225 |
(+231224 2회독, 240225 3회독)
개선된 점
- 재귀 쓸 생각을 하다,,
놓쳤던 점
- 재귀함수의 매개변수와 종료 조건 작성 부분
- 현재 위치의 괄호를 제거할지, 안 할지 코드로 작성하는 부분
// 현재 위치 괄호 제거 X
comb(depth + 1);
// 현재 위치 괄호 제거
int[] now = list.get(depth);
check[now[0]] = true;
check[now[1]] = true;
comb(depth + 1);
check[now[0]] = false;
check[now[1]] = false;
코드 확인하기
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
import java.util.*;
import java.io.*;
public class Main {
static char[] ch;
static Stack<Integer> st;
static List<int[]> list = new ArrayList<>(); // (여는 괄호, 닫는 괄호 위치) 저장 리스트
static boolean[] check; // 해당 위치 괄호 지울지 말지 판단용 배열
static Set<String> result = new TreeSet<>(); // 결과 저장용 집합
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
ch = br.readLine().toCharArray();
st = new Stack<>();
for(int i = 0 ; i < ch.length ; i++) {
if(ch[i] == '(') {
st.push(i);
}
else if(ch[i] == ')') {
list.add(new int[] {st.pop(), i});
}
}
// 괄호 쌍 제거
check = new boolean[ch.length];
comb(0);
for(String s : result) {
sb.append(s).append("\n");
}
System.out.println(sb);
}
private static void comb(int depth) {
if(depth == list.size()) {
StringBuilder tmp = new StringBuilder();
boolean isRemoved = false; // 괄호가 1개 이상 제거되었는지 나타냄
for(int i = 0 ; i < ch.length ; i++) {
if(!check[i]) {
tmp.append(ch[i]);
}
else {
isRemoved = true;
}
}
if(isRemoved) {
result.add(tmp.toString());
}
return;
}
// 현재 위치 괄호 제거 X
comb(depth + 1);
// 현재 위치 괄호 제거
int[] now = list.get(depth);
check[now[0]] = true;
check[now[1]] = true;
comb(depth + 1);
check[now[0]] = false;
check[now[1]] = false;
}
}
|
cs |
(참고)
✔ 풀이 참고
[BOJ] 백준 2800번 괄호 제거 (Java)
#2800 괄호 제거 난이도 : 골드 5 유형 : 문자열 / 조합 2800번: 괄호 제거 첫째 줄에 음이 아닌 정수로 이루어진 수식이 주어진다. 이 수식은 괄호가 올바르게 쳐져있다. 숫자, '+', '*', '-', '/', '(', ')'
loosie.tistory.com
[백준] 2800. 괄호 제거 (자바 JAVA)
[ 문제 ] [백준] 2800. 괄호 제거 (자바 JAVA) 문제 링크 : https://www.acmicpc.net/problem/2800 2800번: 괄호 제거 첫째 줄에 음이 아닌 정수로 이루어진 수식이 주어진다. 이 수식은 괄호가 올바르게 쳐져있다.
ilmiodiario.tistory.com
백준 2800 괄호 제거 (Java,자바)
이번에 풀어본 문제는 백준 2800번 괄호 제거 입니다.
velog.io
[백준 2800] 괄호 제거 (JAVA)
https://www.acmicpc.net/problem/2800스택을 통해 괄호를 짝지어주고 재귀를 통해 괄호를 표시할지 말지 결정 후 나온 식을 HashSet이나 TreeSet을 이용해 중복을 제거해줍니다.(HashSet 경우 정렬을 후 출력해
velog.io
✔ set 원소 출력 방법
자바 Set 사용법부터 출력까지
일단 자바의 Set을 알아보기에 앞서서 List를 알아두면 참 좋은데 List에 대해서는 아래 글을 참고해주면 된다 자바 List 정의부터 출력까지 List는 자바의 자료형 중 하나로 배열과 비슷하지만 결정
wakestand.tistory.com
'코테 > 백준' 카테고리의 다른 글
[백준/JAVA] 4396번: 지뢰 찾기 (0) | 2023.12.13 |
---|---|
[백준/JAVA] 20546번: 🐜 기적의 매매법 🐜 (1) | 2023.12.11 |
[백준/JAVA] 10799번: 쇠막대기 (0) | 2023.12.08 |
[백준/JAVA] 20002번: 사과나무 (1) | 2023.12.08 |
[백준/JAVA] 2346번: 풍선 터뜨리기 (0) | 2023.12.07 |