코딩 테스트/백준

[Python] 백준 4949 균형잡힌 세상

위시리 2024. 9. 10. 19:44

 

문제 분석

  • 모든 왼쪽 소괄호("(")는 오른쪽 소괄호(")")와만 짝을 이뤄야 한다.
  • 모든 왼쪽 대괄호("[")는 오른쪽 대괄호("]")와만 짝을 이뤄야 한다.
  • 온점만 있다면 종료

 

코드 설계

  • 무한 루프를 돌다가 온점을 만나면 반복문 나오기
  • 온점을 만나지 않았다면 문자열을 받으면서 균형을 이루는지 확인
  • 문장을 받다가 온점을 만나면 "yes" or "no"를 출력하고 다음 반복문

 

정답 코드

1차 - 실패

import sys
from collections import deque

input = sys.stdin.readline

while True :
    sentence = list(input().split())
    d = deque()

    if sentence == ".": # finish option
       break

    for s in sentence :
       if s == "(" :
          d.append(s)
       if s == "[" :
          d.append(s)
       if s == ")" :
          if s[-1] == "(":
             d.popleft()
       if s == "]" :
          if s[-1] == "[" :
             d.popleft()
       if s == ".":
          break

    if s :
       print("no")
    else :
       print("yes")
  • 무한루프 : " . "을 만나도 끝나지 않음
  • 7문장 입력 -> 7개의 출력을 하는데 다 "no"
  • 띄어쓰기를 기준으로 입력을 받아짐
  • list로 받지 말고 문자열로 받아서 문자열에 대해서 반목문 
  • 그리고 d에 대해서 검사를 해야하는데 s에 대해서 검사를 진행해서 무한 루프 발생
  • " . "에서 break를 하니, 굳이 s를 검사하면서 다시 "."을 검사할 필요 x

 

2차 - 실패 (IndexError: deque index out of range)

  • 닫힘 괄호에서 주의
  • 닫힘 괄호가 나왔을 때 
  • d가 비어있다면 불균형
  • d가 비어있지 않고, 마지막이 균형을 이루는 열린 괄호라면 pop( )
import sys
from collections import deque

input = sys.stdin.readline

while True :
	sentence = input()
	d = deque()

	if sentence == ".": # finish option
		break

	for s in sentence :
		if s == "(" or s == "[" : # 열린 괄호 : 덱에 추가
			d.append(s)
		elif s == ")" : # 닫힌괄호
			if len(s) != 0 and d[-1] == "(" : # 균형을 이루는 괄호가 들어있으면
				d.popleft() # 비우기
			else : # 균형을 이루는 괄호가 없으면
				d.append(s) # 넣기
				break # 열린 괄호가 없는데 닫힌게 나왔다 > 불균형
		elif s == "]" :
			if len(s) != 0 and d[-1] == "[" :
				d.popleft()
			else :
				d.append(s)
				break
		elif s == "." :
			break

	if d :
		print("no")
	else :
		print("yes")

.Traceback (most recent call last):
  File ".\beak_4949.py", line 17, in <module>
    if len(s) != 0 and d[-1] == "(" : # 균형을 이루는 괄호가 들어있으면
                       ~^^^^
IndexError: deque index out of range

 

3차 - 성공!

  • 미쳤나봐.. len(s) -> len(d)
  • popleft( ) 는 d 배열의 첫번째 항을 제거.. pop( )을 써야함
  • 변수 좀 더 신경써서 정하기.. 자꾸 혼동해서 쓰는 이슈 발생..
  • 그리고
input = sys.stdin.readline
  • 을 하니까 마지막 "."하나만 있을 때 종료가 안됨
  • 코드에서 sys.stdin.readline()을 사용하면 입력된 문자열의 끝에 자동으로 개행 문자(\n)가 추가됩니다. 그래서 입력으로 "."을 받으면 실제로는 "." + "\n"이 입력되어, "sentence == '.'" 조건이 거짓으로 평가

 

  • input = sys.stdin.readline 처리 후 입력을 받으면 입력된 문자열 끝에 자동으로 개행문자가 추가 됨. 이는 입력을 받을 때 
sentence = input().strip()

와 같이 strip( )로 불필요한 개행문자나 공백을 제거할 수 있는데 이러면 또 문제가 strip( ) 함수를 사용함으로써 양 끝의 공백을 제거함. 즉, "."과 " ."을 구분할 수 없음

따라서 문자 끝부분에서만 개행 문자를 제거하기 위해 

sentence = input().rstrip()

와 같이 코드를 작성할 수 있음

import sys
from collections import deque
input = sys.stdin.readline

while True :
    sentence = input().rstrip()
    d = deque()

    if sentence == ".": # finish option
       break

    for s in sentence :
       if s == "(" or s == "[" : # 열린 괄호 : 덱에 추가
          d.append(s)
       elif s == ")" : # 닫힌괄호
          if len(d) != 0 and d[-1] == "(" : # 균형을 이루는 괄호가 들어있으면
             d.pop() # 비우기
          else : # 균형을 이루는 괄호가 없으면
             d.append(s) # 넣기
             break # 열린 괄호가 없는데 닫힌게 나왔다 > 불균형
       elif s == "]" :
          if len(d) != 0 and d[-1] == "[" :
             d.pop()
          else :
             d.append(s)
             break
       elif s == "." :
          break

    if d :
       print("no")
    else :
       print("yes")