백준 2504번 괄호의 합 링크 : 

    https://www.acmicpc.net/problem/2504

 

2504번: 괄호의 값

4개의 기호 ‘(’, ‘)’, ‘[’, ‘]’를 이용해서 만들어지는 괄호열 중에서 올바른 괄호열이란 다음과 같이 정의된다. 한 쌍의 괄호로만 이루어진 ‘()’와 ‘[]’는 올바른 괄호열이다.  만일 X가 올바른 괄호열이면 ‘(X)’이나 ‘[X]’도 모두 올바른 괄호열이 된다.  X와 Y 모두 올바른 괄호열이라면 이들을 결합한 XY도 올바른 괄호열이 된다. 예를 들어 ‘(()[[]])’나 ‘(())[][]’ 는 올바른 괄호열이지만 ‘([)]’ 나 ‘(()(

www.acmicpc.net

2504번 문제 설명

괄호의 합은 두 가지 로직이 필요한 문제였다. 

 

    - 괄호가 잘 닫혀있는 지 확인

    - 괄호의 합을 계산

 

괄호가 잘 닫혀있는 지 확인 (불가능한 형태인지 확인)

    - Stack을 사용하여 연 괄호 '(', '['를 닫는 괄호 ')', ']'로 전부 잘 닫히는 지 확인한다.

        -> 연 괄호일 때 push, 닫는 괄호 일 때 stack top 괄호 모양 확인 후 pop

        -> 닫는 괄호와 연 괄호가 매칭되지 않으면 불가능한 형태이다. 중지하고 0을 출력한다.

        -> input string을 전부 탐색한 후에 stack이 비어있지 않으면 (잘 닫힌 것이 아니면) 불가능으로 판단

 

    - 여는 괄호의 갯수와 닫는 괄호의 갯수를 확인한다.

        -> 이 부분 때문에 조금 애먹었다.

        -> '(((((()))' 왼쪽과 같은 여는, 닫는 괄호의 수가 일치하지 않은 경우를 감지하기 위해,

             (), [] 형태마다 변수를 두어 괄호의 수를 체크한다. 여는 괄호일 때는 +1, 닫는 괄호일 땐 -1

 

괄호의 합을 계산

    - 괄호의 합을 계산하기 위해서는 분배 법칙을 적용된 식을 이해해야 한다. (a x (b + c) = a x b + a x c)

 

    - 괄호 안에 괄호가 정의되는 경우와 괄호가 끝나 괄호끼리 +하는 경우를 위해 몇 가지 규칙이 필요하다.

         -> 괄호가 열리는 순간 depth가 깊어진다고 가정한다.

              ( () 모양 괄호는 x2 depth, [] 모양 괄호는 x3 depth )

         -> 괄호가 열린 후 바로 닫힐 때는 +를 수행한다. ')' 모양일 때 바로 전 모양이 '(' 이면 +를 수행하는 식

         -> 괄호가 닫히는 순간 depth를 하나 벗어난다고 본다.

              ( (X), '()' 모양의 괄호를 벗어나면 /2, '[]' 모양의 괄호를 벗어나면 /3 )

 

    - 규칙에 따라 적용하면 문제의 예시 앞부분은 다음과 같이 풀이 될 수 있다.

         -> 예시 : "(()[[]])" , 초기 값 depth = 1, 초기 값 sum = 0

         -> 0번째 ( : depth x 2                      || depth = 2, sum = 0, 전체에 x2를 한 상태와 같음

         -> 1번째 ( : depth x 2                      || depth = 4,  sum = 0

         -> 2번째 ) : sum += depth, depth / 2  || depth = 2,  sum = 4

         -> 3번째 [ : depth x 3                      || depth = 6,  sum = 4

         -> 4번째 [ : depth x 3                      || depth = 18, sum = 4

         -> 5번째 ] : sum += depth, depth / 3  || depth = 6,  sum = 22

         -> 6번째 ] : depth / 3                      || depth = 2,  sum = 22

         -> 7번째 ) : depth / 2                      || depth = 1,  sum = 22

         -> 최종 값 : 22

         -> 손으로 계산해본 "(()[[]])" 값과 같음! =>> 2 x (2 + (3x3)) = 4 + 18 = 22

 

 * 구현 코드

input_data = input()
# input_data = "(()[[]])([])"

class Stack(list):
    push = list.append    
    def is_empty(self):   
        if not self:
            return True
        else:
            return False

    def peek(self): 
        if self.is_empty():
            return ""
        else :
            return self[-1]

stack = Stack()

mul_depth = 1
total_sum = 0
impossible = 0
s = 0
l = 0
leng = len(input_data)

for idx in range(leng):
    brk = input_data[idx]
    if brk.__eq__("("):
        s += 1
        mul_depth = mul_depth * 2
        stack.push(brk)

    elif brk.__eq__("["):
        l += 1
        mul_depth = mul_depth * 3
        stack.push(brk)

    elif brk.__eq__(")"):
        s -= 1
        if not stack.peek().__eq__("("):
            impossible = 1
            break

        if input_data[idx-1].__eq__('('):
            total_sum += mul_depth
        
        mul_depth = mul_depth / 2
        stack.pop()

    elif brk.__eq__("]"):
        l -= 1
        if not stack.peek().__eq__("["):
            impossible = 1
            break

        if input_data[idx-1].__eq__('['):
            total_sum += mul_depth
        
        mul_depth = mul_depth / 3
        stack.pop()

if (stack.is_empty == 0) or impossible or l or s:
    print(0)
else :
    print(int(total_sum))

'알고리즘' 카테고리의 다른 글

[프로그래머스 Lv 3] 상담원 인원  (1) 2023.07.29
My github as algorithm hub  (0) 2021.06.16
[이코테] 구현 - 게임 개발  (0) 2021.06.13

+ Recent posts