--- 栈 (Stack) --- 后进先出 (LIFO) 平时可以用 list 来实现 (append & pop),封装成类更严谨
class Stack(object):
def __init__(self):
self.stack = []
def push(self, element):
self.stack.append(element)
def pop(self):
if not self.is_empty():
return self.stack.pop()
else:
return None
def get_top(self):
if not self.is_empty():
return self.stack[-1]
else:
return None
def is_empty(self):
return len(self.stack) == 0
栈的应用:
括号匹配
def parentheses_match(s):
"""括号匹配"""
stack = Stack()
match = {')':'(', ']':'[', '}':'{'}
for ch in s:
if ch in {'(', '[', '{'}:
stack.push(ch)
else:
if stack.is_empty():
return False
elif stack.get_top() == match[ch]:
stack.pop()
else:
return False
if stack.is_empty():
return True
else:
return False
进制转换
def base_convert(n, base):
"""十进制转换成十六以下任意进制"""
digits = '0123456789ABCDEF'
stack = Stack()
res = ''
# 余数 push 进栈:低位 --> 高位
while n > 0:
remainder = n % base
stack.push(remainder)
n //= base
# pop 输出:高位 --> 低位
while not stack.is_empty():
res += digits[stack.pop()]
return res
中缀表达式转换成后缀表达式
def infix_to_postfix(infix):
"""中缀表达式转换成后缀表达式"""
# 操作符的优先级
prec = {'*':3, '/':3, '+':2, '-':2, '(':1}
stack = Stack()
token = infix.split()
postfix = []
for t in token:
# t == 操作数,直接添加到后缀表达式列表末尾
if t != ')' and t not in prec.keys():
postfix.append(t)
# t == '(',压入栈顶
elif t == '(':
stack.push(t)
# t == ')',反复 pop() 栈顶操作符,添加到列表,直到碰到 '('
elif t == ')':
top = stack.pop()
while top != '(':
postfix.append(top)
top = stack.pop()
# t == 操作符,比较其与栈顶操作符的优先级
# 若栈顶 >= 它,反复 pop() 栈顶操作符,添加到列表
# 直到栈顶操作符的优先级低于它,压入栈顶
else:
while not stack.is_empty() and prec[stack.get_top()] >= prec[t]:
postfix.append(stack.pop())
stack.push(t)
# 栈中剩余操作符依次弹出,添加到列表
while not stack.is_empty():
postfix.append(stack.pop())
return ''.join(postfix)
后缀表达式求值
def postfix_cal(postfix):
"""后缀表达式求值"""
stack = Stack()
token = postfix.split()
for t in token:
# 暂存操作数
if t in '0123456789':
stack.push(int(t))
# 碰到操作符时,再将暂存的两个操作数进行实际计算
# 计算后,压入栈顶,方便后续计算
else:
num2 = stack.pop()
num1 = stack.pop()
res = do_math(t, num1, num2)
stack.push(res)
# 所有操作符处理完毕,栈中留下唯一操作数,即为结果
return stack.pop()
def do_math(op, num1, num2):
if op == '+':
return num1 + num2
elif op == '-':
return num1 - num2
elif op == '*':
return num1 * num2
else:
return num1 / num2