본문 바로가기
✅ 문제풀이

프로그래머스 - 괄호변환 파이썬 python

by dogfoot.dev 2021. 11. 18.
728x90
728x90

프로그래머스 Level 2 괄호변환 파이썬 문제 풀이 입니다.

링크 : https://programmers.co.kr/learn/courses/30/lessons/60058?language=python3 

 

코딩테스트 연습 - 괄호 변환

카카오에 신입 개발자로 입사한 "콘"은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를

programmers.co.kr

 

✅ Python3 답안 입니다 더보기 클릭!

 

더보기
def divide(p):
    open_ = 0
    closed_ = 0
    # (과 )의 갯수가 같다면 나눈다
    for i,pp in enumerate(p):
        if pp == "(":
            open_ +=1
        elif pp ==")":
            closed_ +=1
        if open_ == closed_:
            # 나눈다
            u = p[:i+1]
            v = p[i+1:]
            print("u:",u)
            print("v:",v)
            return u,v

def isCorrect(x):
    if x[0] ==")":
        return False
    if x[-1] =="(":
        return False
    return True


def solution(p):
    if not p: # 1. 
        return ""
    u = ""
    v = ""
    u,v = divide(p) #2. 
    if isCorrect(u):
        return u + solution(v) #3
    else: #4
        answer="("
        answer += solution(v)
        answer += ")"
        for uu in u[1:len(u) - 1]:
            if uu == '(':
                answer += ')'
            else:
                answer += '('
        return answer

 

 

📌 해설

로직을 문제에서 줬는데 이걸 올바르게 해석하고 코드로 옮겨올 수 있는지가 중요했던 문제였습니다. 

이 문제처럼 솔루션 로직을 글로 준 경우 머리 속에 있는 코드를 많이 구현해 보는 연습이 필요합니다. 

아래 해설에서도 문제에서 제공한 로직을 그대로 따라가 보겠습니다.

 

def solution(p):
    if not p: # 1. 
        return ""
    u = ""
    v = ""

1. 입력이 빈 문자열인 경우 빈 문자열을 반환합니다. 그리고 u와 v를 빈 문자열로 초기화 해주었습니다. 

 

u,v = divide(p) #2.
def divide(p):
    open_ = 0
    closed_ = 0
    # (과 )의 갯수가 같다면 나눈다
    for i,pp in enumerate(p):
        if pp == "(":
            open_ +=1
        elif pp ==")":
            closed_ +=1
        if open_ == closed_:
            # 나눈다
            u = p[:i+1]
            v = p[i+1:]
            print("u:",u)
            print("v:",v)
            return u,v

2. 문자열을 u와 v로 분리합니다. 단, u는 더 이상 분리할 수 없어야 하며 v는 빈 문자열이 될 수 있습니다. 

    2-1. 문자열은 "균형잡힌 괄호 문자열" u,v로 분리 되어야 합니다. 따라서 open_의 갯수와 closed_의 갯수를 세어 같아졌을때를 기준으로 분리합니다.

    2-2. 앞부분의 부분 문자열을 u, 뒷부분의 부분 문자열을 v라고 하고 반환합니다.

이때 u는 더이상 분리할 가능성이 없습니다. 반면 v는 더 분리할 수 있습니다. 

u는 이미 앞서 (갯수와 )갯수가 같은 부분 문자열이기 때문에 만약 divde(u)를 하게 되어도 u와 빈 문자열 ""가 반환될것입니다. 

 

    if isCorrect(u):
        return u + solution(v) #3
def isCorrect(x):
    if x[0] ==")":
        return False
    if x[-1] =="(":
        return False
    return True

3. 문자열 u가 '올바른 괄호 문자열'이라면 문자열 v에 대해 1. 부터 다시 수행합니다. isCorrect는 해당 부분 문자열의 처음 글자, 또는 마지막 글자를 검사합니다.

처음 글자가 ")"닫힘 기호이면 올바르지 않습니다. 

마지막 글자가 "("열림 기호이면 올바르지 않습니다.

올바른 부분 문자열은 처음 글자는 "("열림 기호 마지막 글자는 ")" 닫힘 기호여야 합니다. 

isCorrect는 앞 부분문자열 u에만 시행하기 때문에 u의 특성(더 divide할 수 없음, 열림괄호, 닫힘 괄호 갯수가 같음)으로 인해 해당 조건문만으로 올바른 괄호 문자열인지 아닌지 판별할 수 있습니다.

    3-1. 수행한 결과를 문자열 u에 이어 붙인 후 반환합니다. 

 

    else:#4
        answer="("
        answer += solution(v)
        answer += ")"
        for uu in u[1:len(u) - 1]:
            if uu == '(':
                answer += ')'
            else:
                answer += '('
        return answer

4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다. 

    4-1. 빈 문자열(anwer)에 "("를 붙입니다.

    4-2. 문자열 v에 대해 1. 부터 재귀적으로 수행한 결과를 answer에 이어 붙입니다. 

    4-3. answer에 ")"를 다시 붙입니다. 

    4-4. u의 첫번째와 마지막 문자를 제거하고 나머지 문자열의 괄호 방향을 뒤집어 answer에 붙입니다. 

    4-5. 생성된 문자열을 반환합니다.

 

 

 

728x90
반응형