[Baekjoon] 1935/후위 표기식2/Python/파이썬/자료구조/stack

·2025년 1월 7일
0

문제풀이

목록 보기
12/56
post-thumbnail

💡문제

후위 표기식과 각 피연산자에 대응하는 값들이 주어져 있을 때, 그 식을 계산하는 프로그램을 작성하시오.

입력

첫째 줄에 피연산자의 개수(1 ≤ N ≤ 26) 가 주어진다. 그리고 둘째 줄에는 후위 표기식이 주어진다. (여기서 피연산자는 A~Z의 영대문자이며, A부터 순서대로 N개의 영대문자만이 사용되며, 길이는 100을 넘지 않는다) 그리고 셋째 줄부터 N+2번째 줄까지는 각 피연산자에 대응하는 값이 주어진다. 3번째 줄에는 A에 해당하는 값, 4번째 줄에는 B에 해당하는값 , 5번째 줄에는 C ...이 주어진다, 그리고 피연산자에 대응 하는 값은 100보다 작거나 같은 자연수이다.

후위 표기식을 앞에서부터 계산했을 때, 식의 결과와 중간 결과가 -20억보다 크거나 같고, 20억보다 작거나 같은 입력만 주어진다.

출력

계산 결과를 소숫점 둘째 자리까지 출력한다.

예제입력

5
ABC*+DE/-
1
2
3
4
5

예제출력

6.20

📖내가 작성한 Code

import sys


class Node:
    def __init__(self, data):
        self.data = data
        self.next = None


class Stack:
    def __init__(self, mathematical_expression):
        self.top_node = None
        self.mathematical_expression = mathematical_expression
        self.alphabet_dict = {chr(alpha): 0 for alpha in range(ord('A'), ord('Z')+1)}

    def make_alphabet_dict(self, alphabet):
        self.alphabet_dict[chr(alphabet)] = int(sys.stdin.readline().rstrip())

    @staticmethod
    def elementary_arithmetic(number1, number2, data):
        match data:
            case '+':
                return number1 + number2
            case '-':
                return number1 - number2
            case '*':
                return number1 * number2
            case '/':
                if number2:
                    return number1 / number2
                raise ZeroDivisionError
            case _:
                raise TypeError

    def calculate_mathematical_expression(self):
        for char in self.mathematical_expression:
            if char.isalpha():
                new_node = Node(self.alphabet_dict[char])
                if self.top_node:
                    new_node.next = self.top_node
                self.top_node = new_node
            else:
                number2 = self.top_node.data
                number1 = self.top_node.next.data
                self.top_node = self.top_node.next.next
                new_node = Node(Stack.elementary_arithmetic(number1, number2, char))
                if self.top_node:
                    new_node.next = self.top_node
                self.top_node = new_node

        return self.top_node.data


def main():
    number = int(sys.stdin.readline().rstrip())
    mathematical_expression = sys.stdin.readline().rstrip()
    new_stack = Stack(mathematical_expression)
    start_alphabet = ord('A')

    for num in range(number):
        new_stack.make_alphabet_dict(start_alphabet)
        start_alphabet += 1

    print("{:.2f}".format(new_stack.calculate_mathematical_expression()))


if __name__ == '__main__':
    main()


✍️풀이과정

단순한 stack 문제라고 생각해서 바로 구현. @staticmethod도 써보고 range(ord('A'), ord('Z')+1)도 해봄.


🧠 코드 리뷰

  1. 스택 구현은 파이썬 내장 list 사용 고려
  2. 입력값을 float으로 읽고 처리
  3. 예외 처리를 좀 더 견고하게 할 수 있음
  4. 필요하다면 match ~ case 대신 딕셔너리 매핑을 쓰거나, 단순 if-elif를 쓰는 방식도 유지 보수성이 좋을 수 있습니다.

🛠️AI 개선 코드

import sys

def main():
    input = sys.stdin.readline
    # 1) 피연산자 개수 입력
    N = int(input().strip())
    # 2) 후위 표기식(문자열) 입력
    expression = input().strip()

    # 3) 알파벳-값 매핑 딕셔너리 생성
    values = {}
    for i in range(N):
        # A부터 차례대로 값 입력받아 float로 저장
        alpha = chr(ord('A') + i)
        values[alpha] = float(input().strip())

    # 4) 스택(파이썬 리스트 사용) 초기화
    stack = []

    # 5) 후위 표기식 순회하며 계산
    for char in expression:
        if char.isalpha():
            # 피연산자면 스택에 push
            stack.append(values[char])
        else:
            # 연산자면 스택에서 2개 pop 후 계산
            b = stack.pop()
            a = stack.pop()

            # match-case 문 (파이썬 3.10+)
            match char:
                case '+':
                    stack.append(a + b)
                case '-':
                    stack.append(a - b)
                case '*':
                    stack.append(a * b)
                case '/':
                    # 0으로 나누는 경우 예외 처리(필요 시)
                    if b == 0:
                        raise ZeroDivisionError("0으로 나눌 수 없습니다.")
                    stack.append(a / b)
                case _:
                    raise TypeError(f"알 수 없는 연산자: {char}")

    # 6) 스택에 남은 결과(마지막 값) 가져오기
    result = stack.pop()

    # 7) 소숫점 둘째 자리까지 출력 (반올림)
    print(f"{result:.2f}")


if __name__ == "__main__":
    main()

💻결과

백준문제 보러가기


🖱️참고 링크

자료구조 Python 공식문서

profile
우물 안에서 무언가 만드는 사람

0개의 댓글