栈的基本介绍
出栈(pop)示意图
入栈(push)示意图
栈的应用场景
数组模拟栈
思路分析
代码实现
# 用数组模拟栈
class ArrayStack:
def __init__(self, size):
self.max_size = size # 栈的最大容量
self.top = -1 # top 表示栈顶
self.stack = [] # 用列表表示数组
# 判断栈满
def is_full(self):
return self.top == self.max_size - 1
# 判断栈空
def is_empty(self):
return self.top == -1
# 入栈
def push(self, ele: int):
if self.is_full():
print("栈已满")
else:
self.top += 1
self.stack.insert(self.top, ele)
# 出栈
def pop(self) -> int:
if self.is_empty():
print("栈空")
else:
val = self.stack.pop(self.top)
self.top -= 1
return val
# 获取栈顶元素
def get_top(self):
if self.is_empty():
return
return self.stack[self.top]
# 遍历栈,从栈顶开始
def for_stack(self):
if self.is_empty():
print("栈空")
return
print("栈元素:", end="")
i = self.top
while i >= 0:
print(self.stack[i], end=" ")
i -= 1
print()
# 测试
def test_array_stack(size):
stack = ArrayStack(size)
while True:
print("=====栈的操作菜单=====")
print("1、入栈")
print("2、出栈")
print("3、显示栈")
print("4、退出")
try:
select = int(input("请选择:"))
except Exception:
print("没有该选项,请重新选择:")
if select == 1:
ele = int(input("请输入元素:"))
stack.push(ele)
elif select == 2:
print("栈顶元素为:", stack.pop())
elif select == 3:
stack.for_stack()
elif select == 4:
break
else:
print("没有该选项,请重新输入")
# 测试
test_array_stack(5)
用栈实现加减乘除综合计算器
思路分析
代码实现
# 用栈实现综合计算器
def calculator(expression: str):
size = len(expression)
num_stack = ArrayStack(size) # 操作数栈
oper_stack = ArrayStack(size) # 操作符栈,存放运算符
# 运算符运算结果
opers = {
"*": lambda x, y: x * y,
"/": lambda x, y: x / y,
"+": lambda x, y: x + y,
"-": lambda x, y: x - y
}
# 运算符优先级
oper_priority = {
"*": 1,
"/": 1,
"+": 0,
"-": 0
}
# 遍历表达式
index = 0
while True:
if index >= len(expression):
break
i = expression[index]
if "0" <= i <= "9": # 是操作数
# 判断下一个字符还是不是数字
next = index + 1
while True: # 直到大于表达式长度或者下一个字符不是数字则退出循环
if next >= len(expression):
break
ch = expression[next]
if "0" <= ch <= "9":
i += ch
index = next
next += 1
else:
break
num_stack.push(i)
else: # 是运算符
# 如果操作符栈为空,则操作符 i 直接入栈
if oper_stack.is_empty():
oper_stack.push(i)
index += 1
continue
# 获取 oper_stack 栈顶的运算符
top = oper_stack.get_top()
priority = oper_priority[i] - oper_priority[top] if top else 0
# 如果当前操作符 i 大于栈顶的操作符,也直接入栈
if priority > 0:
oper_stack.push(i)
# 否则,取出两个操作数和栈顶的操作符进行运算,奖结果入操作数栈,并且将操作符 i 入栈
else:
# 注意,由于栈先进后出,操作数栈顶的数是表达式中操作符右边的数
# 所以 num1 和 num2 两个变量的位置不要弄错
num2 = float(num_stack.pop())
num1 = float(num_stack.pop())
oper = oper_stack.pop()
result = opers[oper](num1, num2)
num_stack.push(result)
oper_stack.push(i)
index += 1
# 遍历表达式完毕后,将两个栈中的操作数和操作符取出进行运算
while not num_stack.is_empty() and not oper_stack.is_empty():
num2 = float(num_stack.pop())
num1 = float(num_stack.pop())
oper = oper_stack.pop()
num_stack.push(opers[oper](num1, num2))
# 最后操作数栈中的结果就是表达式的运算结果
print("{}={}".format(expression, num_stack.pop()))
calculator("50*8+25/6-2*7")
print(50*8+25/6-2*7)