프로그래밍/알고리즘 문제 풀이

[백준] 10828(스택) - Python(파이썬) - 1 (feat. split() 사용법)

춤추는 선인장 2023. 7. 17. 18:30
반응형
SMALL

 
이번문제는 정수를 저장하는 스택 자료구조를 구현하고 주어지는 명령어를 처리하면 되는거라 간단한 문제인줄 알았다...
 
처음엔 스택이라는 클래스를 파이썬 기본 리스트를 활용하여 객체를 만든 뒤 각 명령어들을 input()명령어와 split()을 통해 받아서 실행시켰다. 이렇게 말이다.
 

Stack 파이썬 구현

class stack:

    def __init__(self):
        self.a = []  # 리스트를 활용해 스택 구현
        self.t = 0  # 스택의 크기를 저장할 변수 t 선언

    def push(self, add):  # 인자를 받아 리스트에 추가
        self.a.append(add)
        self.t += 1

    def pop(self):  # 가장 최근에 삽입한 값 출력 및 삭제
        if self.a:
            temp = self.a[-1]
            del self.a[-1]
            print(temp)
            self.t -= 1
        else:
            print(-1)

    def size(self):  # 스택의 크기를 변수 t에 저장해뒀다가 반환
        print(self.t)

    def empty(self):  # 스택이 비어있나 확인
        if self.a:
            print(0)
        else:
            print(1)

    def top(self):  # 가장 최근에 삽입한 값을 제거 없이 출력
        if self.a:
            print(self.a[-1])
        else:
            print(-1)


if __name__ == '__main__':

    a = stack()
    n = int(input())
    for i in range(n):
        cmd = input().upper().split()  #split()을 활용해 리스트로 문자열 받음
        if cmd[0] == "PUSH":
            x = int(cmd[1])
            a.push(x)
        elif cmd[0] == "POP":
            a.pop()
        elif cmd[0] == "SIZE":
            a.size()
        elif cmd[0] == "EMPTY":
            a.empty()
        elif cmd[0] == "TOP":
            a.top()

 
처음 풀었을 때는 구현은 쉬웠으나 PUSH 명령어 후에 정수값을 받아야해서 input()을 어떻게 받아야 할까 고민하던중 split()을 이용하여 풀면 되겠단 생각이 들었다. 
 
split을 쓰면 구분자 혹은 띄어쓰기를 기준으로 문장을 나누어 준다.
 

split()

## 예시
a = "hello world"
a = a.split()
print(a)

## 결과 --> ['hello', 'world']

이런식으로 따로 구분자를 지정해 주지 않으면 띄어쓰기를 기준으로 구분해 리스트로 만들어 준다. 
 
이런식으로 구현해 제출을 하였으나...

현실부정하며 코드를 조금씩 고쳐보았다..

결과는 시간 초과였다...
 
왜 시간초과가뜰까 싶어서 혹시 그냥 기본 리스트로 구현해서 그런가? Linked list로 구현을 해야하나? 싶어서 만들어 봤다.
(실은 파이썬 리스트는 동적배열이라 그냥 써도 된다는걸 난 당시 기억해 내지 못 했다...)

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


class Linkedlist:
    def __init__(self):
        self.head = None
        self.lengthVar = 0

    def size(self):
        return self.lengthVar

    def addHead(self, data):
        preNode = Node(data)
        if self.head is None:  # 머리가 없으면 머리에 노드 추가
            self.head = preNode
        else:  # 머리가 있으면, 현 노드의 다음노드를 현 머리의 주소로 대입하고 현 노드를 머리로
            preNode.next = self.head
            self.head = preNode
        self.lengthVar += 1

    def delHead(self):
        if self.head is None:  # 머리가 없으면 -1 반환
            print(-1)
        else:  # 머리가 있으면 현 머리를 현 머리의 다음으로 놔둠 --> 이렇게 되면 가비지 컬렉터가 알아서 필요없는 노드를 없애줌
            print(self.head.data)
            self.head = self.head.next
            self.lengthVar -= 1


class stack:

    def __init__(self):
        self.ll = Linkedlist()

    def push(self, add):
        self.ll.addHead(add)

    def pop(self):
        self.ll.delHead()

    def size(self):
        self.ll.size()

    def empty(self):
        if self.ll:
            print(0)
        else:
            print(1)

    def top(self):
        if self.ll:
            print(self.ll.head.data)
        else:
            print(-1)


if __name__ == '__main__':

    a = stack()
    n = int(input())
    for i in range(n):
        cmd = input().upper().split()
        if cmd[0] == "PUSH":
            x = int(cmd[1])
            a.push(x)
        elif cmd[0] == "POP":
            a.pop()
        elif cmd[0] == "SIZE":
            a.size()
        elif cmd[0] == "EMPTY":
            a.empty()
        elif cmd[0] == "TOP":
            a.top()

이렇게 구현을 했으나 위에 Linkedlist클래스로 기능들을 만들었는데 굳이 stack클래스를 다시 만들어야 할 필요가 없을것 같아서 다시 만들었다. (런타임 에러가 뜨기도 했고...)
 

Linked list 파이썬 구현

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


class Linkedlist:
    def __init__(self):
        self.head = None
        self.nodeCount = 0  # 노드의 개수를 세어줄 변수 선언

    def size(self):  # 링크드 리스트의 사이즈 반환
        return self.nodeCount

    def addHead(self, data):  # 스택구현을 해야하므로 항상 최신 노드를 상단에 삽입
        preNode = Node(data)
        if self.head is None:
            self.head = preNode
        else: 
            preNode.next = self.head
            self.head = preNode
        self.nodeCount += 1

    def delHead(self):  # 스택구현을 해야하므로 최신 노드 바로 전에 삽입 된 노드를 상단으로
        if self.head is None:  
            print(-1)
        else:  
            print(self.head.data)
            self.head = self.head.next  
            # 이렇게 노드를 건너뛰어주면 필요없어진 메모리를 파이썬의 가비지 컬렉터가 회수해감
            self.nodeCount -= 1


if __name__ == '__main__':

    ll = Linkedlist()
    n = int(input())
    for i in range(n):
        cmd = input().upper().split()
        if cmd[0] == "PUSH":
            x = int(cmd[1])
            ll.addHead(x)
        elif cmd[0] == "POP":
            ll.delHead()
        elif cmd[0] == "SIZE":
            pirnt(ll.size())
        elif cmd[0] == "EMPTY":
            if ll is None:
                print(1)
            else:
                print(0)
        elif cmd[0] == "TOP":
            if ll.head is None:
                print(-1)
            else:
                print(ll.head.data)

런타임 에러가 난것은 stack 클래스를 활용해서 굳이 두번 불러온것과 상관 없이 top에서 참조를 잘못해서 난것이였지만, 아무튼 이렇게 해서 제출을 완료하였다!!
 
결과는...

왜?

틀렸다..? 
 
 
----> 2편에서 계속.
 
 
split() 관련 documentation
https://docs.python.org/3/library/stdtypes.html#str.split

 

Built-in Types

The following sections describe the standard types that are built into the interpreter. The principal built-in types are numerics, sequences, mappings, classes, instances and exceptions. Some colle...

docs.python.org

다음편 --> https://leedongchan.tistory.com/entry/%EB%B0%B1%EC%A4%80-10828%EC%8A%A4%ED%83%9D-Python%ED%8C%8C%EC%9D%B4%EC%8D%AC-2-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%B9%A0%EB%A5%B8-%EC%9E%85%EC%B6%9C%EB%A0%A5-SYS

 

[백준] 10828(스택) - Python(파이썬) - 2 (feat. 파이썬 빠른 입출력, SYS)

저번시간에 이어서 마저 문제를 풀어보겠다. 나는 문제를 풀던중 어떻게 해도 안된다는것을 알았다. 왜냐면... input()으로 특히 반복적으로 값을 받으면, 시간이 오래 걸려서 시간 초과가 뜨기 때

leedongchan.tistory.com

 

반응형
LIST