Per ardua ad astra !
I'm On My Way
Per ardua ad astra !
전체 방문자
오늘
어제
  • 분류 전체보기 (126)
    • Algorithm (50)
      • 백준 (30)
      • SWEA (3)
      • JUNGOL (3)
      • Programmers (5)
      • LeetCode (2)
    • 안드로이드 개발 (6)
      • Java로 개발 (0)
      • Kotlin으로 개발 (3)
    • Spring (41)
      • Spring기본 (17)
      • JPA기본 (15)
      • JPA활용 SpringBoot 기본 (9)
      • API 개발 기본 (0)
    • 네트워크 (3)
    • 운영체제 (0)
    • Life (3)
      • 책 (0)
      • 자기계발 (1)
      • 일상 (2)
    • 노마드코더 (3)
      • python으로 웹 스크래퍼 만들기 (3)
    • 프로그래밍 언어 (17)
      • Java 기본 (2)
      • 코틀린 기본 (15)

블로그 메뉴

  • 홈
  • 방명록

인기 글

hELLO · Designed By 정상우.
Per ardua ad astra !

I'm On My Way

Algorithm/백준

[Java] BaekJoon 2800. 괄호 제거(골드5) (부분집합) (DFS)

2021. 10. 7. 16:55

문제출처: https://www.acmicpc.net/problem/2800

 

2800번: 괄호 제거

첫째 줄에 음이 아닌 정수로 이루어진 수식이 주어진다. 이 수식은 괄호가 올바르게 쳐져있다. 숫자, '+', '*', '-', '/', '(', ')'로만 이루어져 있다. 수식의 길이는 최대 200이고, 괄호 쌍은 적어도 1개

www.acmicpc.net

 

문제이해

 

목표

어떤 수식이 주어졌을 때, 괄호를 제거해서 나올 수 있는 서로 다른 식의 개수를 계산하는 프로그램을 작성하시오. 괄호를 제거할 때는, 항상 쌍이 되는 괄호끼리 제거해야 한다.
ex) 
입력 : (0/(0))
출력:
(0/0)
0/(0)
0/0

 

풀이

 

1. 괄호쌍의 인덱스를 Stack을 이용하여 찾아서 저장한다.

2. 각 괄호쌍의 제거 or 제거안함을 이용하여 부분집합, 2의 n제곱 만큼의 경우의 수를 탐색한다.  

   => 괄호 제거는 visited[] =falase 로 한다.

  각 경우(재귀가 끝이나서 now==count 일때), visited를 체크하여 true인 것만 출력하면

  괄호를 제거하고 잘 출력 할 수 있다.

 

주의 

괄호를 제거할 때 visited로 하지 않고 StringBuilder로 만들어서 한 쌍, 한 쌍을 제거하면 인덱스가 밀려서 정확하게 괄호를 제거할 수 없다. 원본 String을 유지하면서 따로 visited를 만들어서 true인 것만 출력할 수 있도록 하자

 

소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

import static java.lang.System.in;

public class 괄호제거 {
    private static HashSet<String> answer;
    private static ArrayList<int[]> pairs;
    private static int count;
    private static boolean[] visited;
    private static char[] charArr;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String s = br.readLine();
        pairs = new ArrayList<>();
        answer = new HashSet<>();
        visited = new boolean[s.length()];
        Arrays.fill(visited, true);

        // 괄호 쌍의 인덱스를 찾아서 저장
        charArr = s.toCharArray();
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            if (charArr[i] == '(') {
                stack.add(i);
            } else if (charArr[i] == ')') {
                pairs.add(new int[]{stack.pop(), i});
            }
        }
        count = pairs.size(); // 부분집합으로 탐색해야한 괄호쌍의 size

        removeGaul(0); // 핵심 알고리즘

        // 정답 도출
        answer.remove(s);
        List<String> answerList = new ArrayList(answer);
        Collections.sort(answerList);
        StringBuilder sb = new StringBuilder();
        for (String s1 : answerList) {
            sb.append(s1).append("\n");
        }
        System.out.println(sb);
    }

    private static void removeGaul(int now) { // 부분집합
        if (now == count) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < visited.length; i++) {
                if (visited[i]) {
                    sb.append(charArr[i]);
                }
            }
            answer.add(sb.toString());
            return;
        }

        // 부분집합
        // 괄호를 제거하지 않고 재귀
        int[] pair = pairs.get(now);
        visited[pair[0]] = true;
        visited[pair[1]] = true;
        removeGaul(now + 1);

        // 괄호를 제거하고 재귀
        visited[pair[0]] = false;
        visited[pair[1]] = false;
        removeGaul(now + 1);
    }
}
    'Algorithm/백준' 카테고리의 다른 글
    • [Java] BaekJoon 15591. MooTube(골드5) (그래프 탐색) (DFS) (BFS)
    • [Java] BaekJoon 1182. 부분수열의 합(실버2) (부분집합)(DFS)
    • [Java] BaekJoon 2661. 좋은수열(골드4) (DFS) (백트래킹)
    • [Java] BaekJoon 2758. 로또(골드4) (DFS, DP)
    Per ardua ad astra !
    Per ardua ad astra !
    개발자 지망생이며 열심히 공부하고 기억하기 위한 블로그입니다.

    티스토리툴바