'쌓다'라는 의미로, 데이터를 차곡차곡 쌓아 올린 형태의 선형 자료구조이다.
후입선출 구조 (LIFO, Last In First Out) : 데이터가 순서대로 쌓이며 가장 마지막에 삽입된 자료가 가장 먼저 삭제꼭대기 top, 아랫부분을 바닥 bottom 이라고 한다.스택은 단 2가지 연산을 지원하는 간단한 자료 구조이다.
푸시 (push) 연산팝 (pop) 연산스택은 생성 방식에 따라 2가지로 구분된다.
정적 스택 : 데이터 구조와 크기의 규모가 고정된 스택 (배열로 설계)동적 스택 : 실행 중에 스택의 크기를 늘릴 수 있고, 소비하는 메모리의 양도 변하는 스택 (단방향 연결 리스트로 설계)스택은 여러 가지의 알고리즘을 구현에 있어서 활용도가 높다.
컴퓨터 하드웨어(프로세서)는 어떤 방식으로든 스택을 내부적으로 관리하는 기능을 갖고 있다.
비어 있는 스택 (empty stack)Stack.push(Data) 형태를 통해서 데이터를 쌓을 수 있고,Stack.pop() 형태를 통해서 마지막에 넣은 데이터를 삭제할 수 있다.
그런데, 스택에서 2가지 오류가 발생할 수 있다.
➀ EmptyStack.pop() ⇨ 스택 언더플로우 (Stack underflow)
비어있는 스택에서 원소를 꺼내려 할 때 발생하는 에러
➁ FullStack.push(data) ⇨ 스택 오버플로우 (Stack overflow)
꽉 찬 스택에 원소를 넣으려 할 때 발생하는 에러
여러 방법이 있지만, 대표적으로 배열을 이용하거나 연결 리스트를 이용해서 스택을 추상적 자료 구조로 구현할 수 있다.
스택의 추상적 자료구조 구현을 위한 연산은 다음과 같다.
size() : 현재 스택에 들어 있는 데이터 원소의 수를 구함isEmpty() : 현재 스택이 비어 있는지를 판단 (size() == 0?)isFull() : 현재 스택이 가득 차 있는지 판단push(x) : 데이터 원소 x 를 스택에 추가pop() : 스택에 가장 나중에 저장된 데이터 원소를 제거 (또한, 반환)peek() : 스택에 가장 나중에 저장된 데이터 원소를 참조 (반환), 그러나 제거하지는 않음from doublylinkedlist import Node
from doublylinkedlist import DoublyLinkedList
# 방법 1. 배열로 스택의 자료구조 구현하기
class AraayStack :
def __init__(self) : # 빈 스택 초기화
self.data = []
def size(self) : # 스택의 크기를 리턴
return len(self.data)
def isEmpty(self) : # 스택이 비어있는지 판단 (T/F)
return self.size() == 0
def push(self, item) : # 데이터 원소 추가
self.data.append(item)
def pop(self) : # 데이터 원소 삭제
return self.data.pop()
def peek(self) : # 스택의 마지막 원소 반환
return self.data[-1]
# 방법 2. (양방향/이중) 연결 리스트로 스택의 자료구조 구현하기
class LinkedListStack:
def __init__(self):
self.data = DoublyLinkedList()
def size(self):
return self.data.getLength()
def isEmpty(self):
return self.size() == 0
def push(self, item):
node = Node(item)
self.data.insertAt(self.size() + 1, node)
def pop(self):
return self.data.popAt(self.size())
def peek(self):
return self.data.getAt(self.size()).data
사실 파이썬에 이미 라이브러리가 존재한다.
from pythonds.basic.stack import Stack# 알고리즘 설계
수식을 왼쪽부터 한 글자씩 읽어서 :
여는 괄호를 만나면 스택에 푸시
닫는 괄호를 만나면 :
스택이 비어 있으면 올바르지 않는 수식
스택에서 pop, 쌍을 이루는 여는 괄호인지 검사
맞지 않으면 올바르지 않은 수식
끝까지 검사한 후, 스택이 비어 있어야 올바른 수식
중위 → 후위 표현식 변환 후 계산하기
# 1. 중위표현식의 요소를 반환하는 코드
def splitTokens(exprStr) :
tokens = []
val = 0
valProcessing = False
for c in exprStr :
if c == ‘ ‘ :
continue
if c in ’0123456789’ : # 10진수 처리
val = val * 10 + int(c)
valProcessing = True
else :
if valProcessing :
tokens.append(val)
val = 0
valProcessing = False # 10진수 처리 x
tokens.append(c)
if valProcessing : # 마지막에 10진수 처리 중이었다면
tokens.append(val)
return tokens
# 2. 중위 표현식을 후위 표현식으로 변환하는 코드
from stacks import ArrayStack as Stack
def infixToPostfix(tokenList) :
price = {‘*’: 3, ‘/‘: 3, ‘+’: 2, ‘-‘: 2, ‘(‘: 1}
opStack = Stack()
postfixList = []
for token in tokenList :
if type(token) is int :
pass
elif token == ‘(‘ :
pass
elif token == ‘)’ :
pass
else :
pass
while not opStack.isEmpty() :
pass
return postfixList
# 3. 후위 표기 수식 계산 코드
from stacks import ArrayStack as Stack
def postfixEval(tokenList) :
valStack = Stack()
for token in tokenList :
if type(token) is int :
pass
elif token == ‘*’ :
pass
elif token == ‘*’ :
pass
elif token == ‘*’ :
pass
elif token == ‘*’ :
pass
return valStack.pop()
def solution(expr) :
tokens = splitTokens(expo)
Postfix = infixToPostfix(tokens)
val = postfixEval(Postfix)
return val
출처
programmers
roi-data.com