본 포스팅은 아래의 출처를 참고하여 정리한 것입니다.
https://www.youtube.com/watch?v=PIidtIBCjEg&list=PLsMufJgu5933ZkBCHS7bQTx0bncjwi4PK&index=1
push
pop
append
= stack의 push
pop
= stack의 pop
top
: stack의 맨 위의 값을 리턴, pop과 다른 점은 그 값을 지우지 않는다는 것len
: stack에 저장된 원소의 총 개수class Stack:
def __init__(self): # 생성 함수
self.items = [] # 데이터 저장을 위한 리스트 준비
def push(self, val):
self.items.append(val)
def pop(self):
try: # pop할 아이템이 있으면
return self.items.pop()
except IndexError:
print("Stack is Empty")
def top(self):
try:
return self.items[-1]
except IndexError:
print("Stack is empty")
def __len__(self): # len() 호출하면 stack의 item 수 반환
return len(self.items)
push
, pop
, top
, len
: 모두 len
: self.items 라는 리스트에서 항상 몇 개인지 관리하고 있기 때문에 값만 리턴해주면 되기때문문제
입력: 왼쪽, 오른쪽 괄호의 문자열
출력: 괄호 쌍이 맞춰져있으면 True, 아니면 False 반환
stack에서 왼쪽 괄호 push 해두고, 오른쪽 괄호를 만날 때까지 pop할 대기
오른쪽 괄호 만났을 때 pop할 왼쪽 괄호가 없다면 올바른 괄호 쌍이 아닌 것
문자열 끝까지 갔을 때 stack이 비어있으면 올바른 괄호 쌍
혹은, 문자열 끝까지 갔을 때 stack이 비어있지 않으면 올바른 괄호 쌍이 아닌 것
S = Stack()
for p in parseq:
if p == '(': S.push(p)
elif p == ')': S.pop() # 여기서 error 발생하면 오른쪽 괄호가 더 많다는 것
else: print("Not allowed Symbol")
if len(S) > 0: return False # 왼쪽 괄호가 더 많음
else: return True
2 + 3 * 5 ➡️ '2', '+', '3', '*', '5'
연산자 우선순위에 따른 계산: (2 + (3 * 5)) = 17
[예제에서 살펴볼 것] 이항 연산자 (binary operator)
infix 수식 ➡️ postfix 수식
A + B * C ➡️ A B C * +
+는 push 되었다가 더 높은 우선순위 만날 때까지 대기
*은 더 우선순위가 높은 연산자가 없으므로 push 됨
+는 자기보다 우선순위가 낮은 연산자를 만났을 때 자기가 나가면 됨
A * B + C ➡️ A B * C +
( A + B ) * C ➡️ A B + C *
왼쪽 괄호 push: 왼쪽 괄호는 우선순위가 제일 낮지만, 일단 무조건 push (다른 연산자 pop 없어)
+는 오른쪽 괄호 다음에 빠져나가야 됨, +를 빼줄 수 있는 연산자는 자기보다 높은 연산자
)는 자신의 짝인 ( 괄호가 있으므로 그 사이에 있는 연산자는 모두 pop 해야 됨 (괄호 안의 연산자는 더 우선시 되어야 하므로)
"""
리스트: outstack (출력 내용이 담길 stack)
스택: opstack
"""
for each token in expr:
if token == operand:
outstack.append(token)
if token == '(':
opstack.push(token)
if token == ')':
# opstack에 저장된 연산자를 '('를 pop할 때까지 모두 pop하여 outstack에 append
if token in ('+*-/'):
# push 되기 전에 opstack에 token보다 높은 우선순위의 연산자는 pop하고 들어감
# opstack에 남은 연산자 모두 pop -> outstack에 담기
for each token in postfix.expr:
if token == operand : s.push(token)
if token in '+-*/':
# 이항 연산자이므로 2개의 항이 필요
a = s.pop()
b = s.pop()
# a와 b를 연산자로 계산 수행 후 결과를 다시 push
s.push(a token b)