문제
세계는 균형이 잘 잡혀있어야 한다. 양과 음, 빛과 어둠 그리고 왼쪽 괄호와 오른쪽 괄호처럼 말이다.
정민이의 임무는 어떤 문자열이 주어졌을 때, 괄호들의 균형이 잘 맞춰져 있는지 판단하는 프로그램을 짜는 것이다.
문자열에 포함되는 괄호는 소괄호("()") 와 대괄호("[]")로 2종류이고, 문자열이 균형을 이루는 조건은 아래와 같다.
- 모든 왼쪽 소괄호("(")는 오른쪽 소괄호(")")와만 짝을 이뤄야 한다.
- 모든 왼쪽 대괄호("[")는 오른쪽 대괄호("]")와만 짝을 이뤄야 한다.
- 모든 오른쪽 괄호들은 자신과 짝을 이룰 수 있는 왼쪽 괄호가 존재한다.
- 모든 괄호들의 짝은 1:1 매칭만 가능하다. 즉, 괄호 하나가 둘 이상의 괄호와 짝지어지지 않는다.
- 짝을 이루는 두 괄호가 있을 때, 그 사이에 있는 문자열도 균형이 잡혀야 한다.
정민이를 도와 문자열이 주어졌을 때 균형잡힌 문자열인지 아닌지를 판단해보자.
입력
하나 또는 여러줄에 걸쳐서 문자열이 주어진다. 각 문자열은 영문 알파벳, 공백, 소괄호("( )") 대괄호("[ ]")등으로 이루어져 있으며, 길이는 100글자보다 작거나 같다. 각 줄은 마침표(".")로 끝난다.
입력의 종료조건으로 맨 마지막에 점 하나(".")가 들어온다.
출력
각 줄마다 해당 문자열이 균형을 이루고 있으면 "yes"를, 아니면 "no"를 출력한다.
문제 풀이
어떤 문자열이 주어졌을 때, 괄호들의 균형이 잘 맞춰져 있는지 판단하는 프로그램이다.
문제에 괄호가 균형을 이루는 조건이 주어져 있는데
결국은 ( 는 ) 와만 짝을 이룰 수 있으며 [ 는 ] 와만 짝을 이룰 수 있다는 것을 나타낸다.
또한 )( 와 ][ 와 같이 반대 방향은 짝을 이룰 수 없다.
만약 한 종류의 괄호만 있었다면 풀이가 좀 더 쉬웠을텐데 두 종류의 괄호가 있어서
풀이를 생각하는 것이 살짝 까다로웠다. 그 이유는 아래와 같이
( [ ) ] 이런 문자열이 주어졌다고 할 때 () 와 [] 만 보면 균형잡힌 괄호 문자열이지만
두 개를 함께 따졌을 때는 짝을 이루고 있지 않으므로 균형잡힌 괄호 문자열이 아니기 때문이다.
따라서 이 문제를 해결하기 위해서는 앞에서부터 차례대로
올바른 방향인지, 짝을 이루는지 확인해줘야 한다.
이를 코드로 구현하기 위해 Stack을 활용하였다.
만약 ( 와 [ 를 만난다면 올바른 방향이므로 먼저 Stack 에 넣어준다.
그런 다음 만약 ) 나 ] 를 만난다면 짝을 이루는지 확인해준다.
예를 들어, ( ( [ ] ) ) 이런 문자열이 있을 경우
Stack에는 ( ( [ 가 저장되어 있을 것이다.
그 후 ] 를 만나면 짝을 이루는지 확인해준다. 짝을 이룬다는 것은
Stack이 비어있지 않고 Stack의 맨 위에 [ 가 저장되어 있어야 한다는 것을 의미한다.
만약 짝을 이룬다면 다음 괄호를 확인하기 위해 Stack의 맨 위에 저장된 것을 삭제해준다.
마찬가지로 ) 를 만났을 때는 Stack이 비어있지 않고 Stack의 맨 위에 ( 가 저장되어 있어야 한다.
만약 짝을 이루지 않는다면 check 변수를 False로 만들어주고 반복문을 빠져나오도록 해주었다.
즉, Stack이 비어있고 check 변수가 True라면 yes를 출력하도록 해주고
나머지 경우에는 no를 출력하도록 해주었다.
My Code
while True:
s = input() # 문자열 입력
if s == '.': # . 입력 시 종료
break
stack = [] # Stack
check = True # 균형잡힌 문자열인지 확인할 변수
for i in s:
if i == '(' or i == '[': # 왼쪽 방향 괄호를 Stack에 삽입
stack.append(i)
elif i == ')': # 오른쪽 방향 괄호를 만났을 때
if stack and stack[-1] == '(': # stack이 비어 있지 않고 짝이 맞다면 삭제
stack.pop()
else: # 짝이 맞지 않는 경우 종료
check = False
break
elif i == ']': # 오른쪽 방향 괄호를 만났을 때
if stack and stack[-1] == '[': # stack이 비어 있지 않고 짝이 맞다면 삭제
stack.pop()
else:
check = False # 짝이 맞지 않는 경우 종료
break
if check and not stack: # 균형잡힌 문자열일 경우
print('yes')
else:
print('no')
'백준(Python) 풀이' 카테고리의 다른 글
백준 3052번. 나머지 (Python / 파이썬) (0) | 2022.07.20 |
---|---|
백준 18111번. 마인크래프트 (Python / 파이썬) (0) | 2022.07.20 |
백준 10989번. 수 정렬하기 3 (Python / 파이썬) (0) | 2022.07.14 |
백준 17626번. Four Squares (Python / 파이썬) (0) | 2022.07.14 |
백준 10816번. 숫자 카드 2 (Python / 파이썬) (0) | 2022.07.12 |
댓글