[Baekjoon] 10828/스택/Python/파이썬/자료구조/Stack

·2024년 12월 2일
0

문제풀이

목록 보기
1/56
post-thumbnail

💡문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 다섯 가지이다.

push X: 정수 X를 스택에 넣는 연산이다.
pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 스택에 들어있는 정수의 개수를 출력한다.
empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

예제입력

14
push 1
push 2
top
size
empty
pop
pop
pop
size
empty
pop
push 3
empty
top

예제출력

2
2
0
2
1
-1
0
1
-1
0
3

📖내가 작성한 Code

import sys


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


class Stack:
    def __init__(self):
        self.top_node = None
        self._size = 0

    def push(self,data):
        if self.top_node is None:
            self.top_node = Node(data)
        else:
            node = Node(data)
            node.next = self.top_node
            self.top_node = node

        self._size += 1

    def pop(self):
        if self.top_node is None:
            return -1

        node = self.top_node
        self.top_node = self.top_node.next
        node.next = None
        self._size -= 1

        return node.data

    def size(self):
        return self._size

    def empty(self):
        return int(self.top_node is None)

    def top(self):
        return self.top_node.data if self.top_node else -1


def main():
    new_stack = Stack()
    test_case = int(input())
    for case in range(test_case):
        command = list(map(str, sys.stdin.readline().split()))
        match command[0]:
            case "push":
                new_stack.push(int(command[1]))
            case "pop":
                print(new_stack.pop())
            case "size":
                print(new_stack.size())
            case "empty":
                print(new_stack.empty())
            case "top":
                print(new_stack.top())


if __name__ == "__main__":
    main()

✍️풀이과정

객체 지향 프로그래밍(OOP)처럼 문제를 풀고 싶었기에 class로 node,stack을 구현.
if-else 구문을 넣으면 쉽게 될 일이지만, 3.10부터 match,case 문법이라는 것이 있길래 사용.
6개월만에 다시 하는거라, 방어코드 없이 구현.

def pop():
	...
	node.next = None // 참조를 끊어 가비지 컬렉터를 메모리에서 해제 시키도록 도와 메모리 누수 방지

Python으로 구현 시에 class,def로 사용하는 이유는

  1. 코드를 논리적 단위로 묶어서 가독성을 높이고 유지보수가 쉬워짐
  2. 캡슐화를 통해 데이터 무결성을 유지
  3. 재사용성 및 확장성 좋아짐
  4. main() 함수 사용하면 코드의 흐름을 파악하기 편해짐(단위 테스트 작성 시 유용해짐)

if name == "main": 구문을 사용하는 이유

  1. 다른 모듈에 import 될 때 동작 구분하여 재사용성 높이고 불필요한 코드 실행 방지

🧠 코드 리뷰

  1. 타입 힌팅 추가 : 코드의 가독성과 유지보수성을 높일 수 있음
    from typing import Optional

    class Node:
        def __init__(self, data: int):
            self.data: int = data
            self.next: Optional['Node'] = None
  1. push 메소드 최적화 : 굳이 if-else는 필요 없었음
    def push(self, data: int) -> None:
            node = Node(data)
            node.next = self.top_node
            self.top_node = node
            self._size += 1
  1. 입력 처리 및 타입 변환 : map으로 변환이 불필요함. 기본적으로 split()는 문자열 리스트 반환
    list(map(str, sys.stdin.readline().split()))
    ->
    sys.stdin.readline().strip().split()

🛠️AI 개선 코드

    import sys
    from typing import Optional

    class Node:
        def __init__(self, data: int):
            self.data: int = data
            self.next: Optional['Node'] = None

    class Stack:
        def __init__(self):
            self.top_node: Optional[Node] = None
            self._size: int = 0

        def push(self, data: int) -> None:
            node = Node(data)
            node.next = self.top_node
            self.top_node = node
            self._size += 1

        def pop(self) -> int:
            if self.top_node is None:
                return -1
            node = self.top_node
            self.top_node = self.top_node.next
            self._size -= 1
            return node.data

        def size(self) -> int:
            return self._size

        def empty(self) -> int:
            return int(self.top_node is None)

        def top(self) -> int:
            return self.top_node.data if self.top_node else -1

    def main():
        new_stack = Stack()
        test_case = int(sys.stdin.readline())
        for _ in range(test_case):
            command = sys.stdin.readline().strip().split()
            if not command:
                continue
            cmd = command[0]
            if cmd == "push":
                if len(command) != 2:
                    print("Error: push 명령어는 하나의 인자를 필요로 합니다.")
                    continue
                try:
                    value = int(command[1])
                    new_stack.push(value)
                except ValueError:
                    print("Error: push 명령어의 인자는 정수여야 합니다.")
            elif cmd == "pop":
                print(new_stack.pop())
            elif cmd == "size":
                print(new_stack.size())
            elif cmd == "empty":
                print(new_stack.empty())
            elif cmd == "top":
                print(new_stack.top())
            else:
                print(f"Error: 알 수 없는 명령어 '{cmd}'가 입력되었습니다.")

    if __name__ == "__main__":
        main()

💻결과

백준문제 보러가기


🖱️참고 링크

Match-case Python 공식문서

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

0개의 댓글