[백준] 2800 - 괄호제거 (Python, combinations)

반응형

BAEKJOON Logo

이번엔 백준 2800 괄호 제거 문제를 풀어보겠습니다. 주요 자료구조는 스택을 사용하며, 조합(combinations)을 이용해 풀어보겠습니다.

 

2800번: 괄호 제거

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

www.acmicpc.net

Contents

*전체 코드

from itertools import combinations
problem = list(input()) # 문제 입력받는 리스트
p, brk_idx = [],[] # 괄호쌍 찾을 스택 -> p , 괄호쌍 인덱스 저장 이중리스트 -> brk_idx
result=set() # 결과 저장할 집합
for i,v in enumerate(problem): ## 괄호쌍 인덱스 저장 및 problem에서 괄호 제거
if v == '(':
problem[i]=''
p.append(i)
if v == ')':
problem[i]=''
brk_idx.append([p.pop(),i])
for i in range(len(brk_idx)): ## 괄호쌍의 조합(combinations)을 이용해 괄호 추가
for j in combinations(brk_idx,i):
P=problem[:] ## problem리스트 복사
for s,e in j:
P[s]='(';P[e]=')' ## 괄호쌍 채우기
result.add(''.join(P))
print(*sorted(result),sep='\n') ## 결과 출력

 

 

문제정의

문제 입력과 출력

입력으로 괄호 쌍이 올바르게 맞는 수식이 주어집니다. (괄호 쌍은 적어도 1개, 많아야 10개) 해당 수식에서 올바른 괄호 쌍을 제거해서 나올 수 있는 서로 다른 식을 사전 순으로 출력해야 합니다. (괄호 쌍이 적어도 1개 이상이기 때문에, 제거되는 괄호 쌍은 1개 이상, 10개 이하)

 

 

import combinations 및 입력부

from itertools import combinations
problem = list(input()) # 문제 입력받는 리스트
p, brk_idx = [],[] # 괄호쌍 찾을 스택 -> p , 괄호쌍 인덱스 저장할 이중리스트 -> brk_idx
result=set() # 결과 저장할 집합

itertools의 combinations를 임포트 해줍니다. 괄호 쌍 조합들을 삽입할 때 쓰입니다. problem에 입력받는 수식을 쪼개 리스트로 저장합니다. p는 스택으로, 괄호 쌍을 찾을 때 사용합니다. brk_idx는 괄호 쌍의 인덱스를 저장할 이중 리스트로 쓰입니다. 결과에 중복을 제거하기 위해 집합(set)을 이용합니다. 예제 입력 1에 대해 problem의 출력은 아래와 같습니다.

* 출력

예제 입력 1에 대한 입력 리스트

 

combinations 간단 설명

combinations(p, r) 일 때, p에 대해 r개수만큼의 조합을 튜플로 출력합니다. 정렬된 순서이며, 반복되는 요소는 없습니다. 아래 예시에선 'ABCD'에서 2개의 조합을 쭉 출력하는 것입니다.

combinations('ABCD', 2) AB AC AD BC BD CD

* 출력

combinations 결과 출력

 

핵심 알고리즘

괄호 쌍 인덱스 저장 및 괄호 제거 리스트 생성

for i,v in enumerate(problem): ## 괄호쌍 인덱스 저장 및 problem에서 괄호 제거
if v == '(':
problem[i]=''
p.append(i)
if v == ')':
problem[i]=''
brk_idx.append([p.pop(),i])

problem리스트를 enumerate를 사용하여, 인덱스(i)와 값(v)을 동시에 차례대로 반복해줍니다. 괄호 시작 부분 '('을 만나면, 스택(p)에 인덱스를 append 하고, 괄호 닫히는 부분 ')'을 만나면 스택(p)에서 pop 한 괄호 시작 부분의 인덱스와 괄호 닫히는 부분의 인덱스를 차례로 리스트로 만들어 brk_idx에 저장합니다. problem에서 괄호 부분은 모두 빈 문자열로 대치해줍니다. (나중에 괄호 쌍을 넣기 위한 용도)

백준의 예제 입력 1번에 대해 위 코드 결과 problem과 brk_idx는 아래와 같습니다.

* 출력

괄호 제거된 problem과 brk_idx

 

괄호 쌍의 조합(combinations)을 이용해 괄호 추가

for i in range(len(brk_idx)): ## 괄호쌍의 조합(combinations)을 이용해 괄호 추가
for j in combinations(brk_idx,i):
P=problem[:] ## problem리스트 복사
for s,e in j:
P[s]='(';P[e]=')' ## 괄호쌍 채우기
result.add(''.join(P))

1. 괄호쌍 인덱스 리스트(brk_idx)에 대해 combinations를 이용 → 추가할 괄호 쌍의 인덱스를 사용합니다.

problem을 재사용하기 위해,

  1. 즉, combinations의 2번째 인자로 0을 넣으면, 추가할 게 없는 경우(모든 괄호가 제외된 경우)가 됩니다.
    -> 0/0
  2. 1을 넣으면 1개의 괄호 쌍을 제외한 경우가 됩니다. 
    -> (0/0), 0/(0)
  3. 주어진 예시에서 괄호 쌍이 총 2개이므로, 이건 돌지 않습니다.

 

print(*sorted(result),sep='\n') ## 결과 출력

괄호 쌍이 제외된 게 중복일 수 있으니, 이를 모두 집합에 추가한 뒤 → sorted(사전 순 정렬) 하여 출력합니다.

* 출력

결과 출력

반응형

댓글

Designed by JB FACTORY