栈实现综合计算器思路及Python实现
思路
- 先建立一个“数栈”用来压入数字,还有一个“符号栈”用来压入运算符,规定:减法从栈底向栈顶方法运算,乘除法优先级高于加减法
- 具体操作过程:以 “3+26-2” 为例
(1)数栈和符号栈皆为空,指针从左向右扫描表达式,数栈入栈第一个数3,符号栈入栈第一个扫描到的运算符‘+’,指针继续移动,遇到‘2’,直接再入数字,此时2在栈顶,3在栈底,指针继续移动遇到运算符‘’
(2)因为 ‘ * ’ 的优先级高于在符号栈栈底的“+”,所以直接将乘法入栈
(3)指针继续移动,遇到6,直接入数栈,指针继续移动,遇到“-”
(4)当前遇到的“-” 先不要入栈,而是从数栈栈pop出栈顶的6,在从字符栈pop出栈顶的“*”,然后再从数栈pop出当前栈顶的2 ;三个元素运算,等到12,将12压入数栈,最后把符号压入符号栈,此时两个栈的栈顶元素分别为:12 和 “-”
(5)指针继续移动,遇到2,压入数栈,此时表达式全部扫描完,就顺序的从数栈和符号pop出数和运算符,并运算,数栈pop出栈顶元素2 符号栈pop出栈顶元素“-” ,数栈再pop出当前栈顶元素12,用规定的“减法从栈底向栈顶方法运算”,所以 是12-2=10,将10 压入数栈,继续pop 数栈栈顶元素10,pop出符号栈“+”,再从数栈pop出元素3,两者运算和为13,将13压入栈,并返回
Python实现
先详细实现 如何 构建一个栈
# 自定义异常
class StackEmptyException(Exception): # 空栈异常
pass
class StackFullException(Exception): # 满栈异常
pass
class Stack(object):
def __init__(self, max_stack):
self.stack = [] # 数组,模拟栈
self.max_stack = max_stack # 栈的大小
self.top = -1 # 栈顶指针,初始化为-1
def is_empty(self): # 栈空
return self.top == -1 # 返回的是一个bool值,注意 是“==”
def is_full(self): # 栈满
return self.top == self.max_stack - 1 # 栈等于.给出的栈大小
def push(self, val): # 压栈
if self.is_full():
raise StackFullException("your stack is full !!!")
self.top += 1
self.stack.insert(self.top, val) # 注意是用的insert,但insert实现时,会增加算法复杂度
'''
insert实现时,会让插入位置后的数组整体移动,从而增加复杂度
如果想用列表提供的索引插入方式(顺序表实现),
不同于Java,因为Python列表在如果当前是空的时候,
会抛出异常:IndexError: list assignment index out of range
异常含义:空数组不能直接指定位置
要解决这个问题,我们可以先给数组加一个值,等用索引插入时,直接覆盖就行
所以上面代码还可以这样写:
self.stack.append(1)
self.top += 1
self.stack[self.top] = val
'''
def pop(self): # 出栈
if self.is_empty():
raise StackEmptyException("your stack is empty !!!")
value = self.stack[self.top]
self.top -= 1
return value
def peek(self): # 返回当前栈顶的值,但不是真正的pop
return self.stack[self.top]
def print_stack(self): # 显示栈的情况,相当于遍历打印
if self.is_empty():
print("空栈,没有数据哦")
return
# 需要从栈顶开始显示数据
for i in range(self.top, -1, -1):
print("stack[%d]=%s" % (i, self.stack[i]))
if __name__ == '__main__':
s = Stack(5)
s.push("第一入栈")
s.push("第二入栈")
s.push("第三入栈")
s.push("第四入栈")
s.push("第五入栈")
s.print_stack() # 直接调用打印方法
# print(s.pop())
# print(s.pop())
# print(s.pop())
# print(s.pop())
# print(s.pop())
# print(s.pop()) # 抛出空栈异常
'''
输出结果:
stack[4]=第五入栈
stack[3]=第四入栈
stack[2]=第三入栈
stack[1]=第二入栈
stack[0]=第一入栈
'''
完整实现 综合计算器的功能
class StackEmptyException(Exception): # 自定义异常,空栈异常
pass
class StackFullException(Exception): # 超栈异常
pass
class Stack(object):
def __init__(self, max_stack):
self.stack = [] # 数组,模拟栈
self.max_stack = max_stack # 栈的大小
self.top = -1 # 栈顶指针,初始化为-1
def is_empty(self): # 栈空
return self.top == -1
def is_full(self): # 栈满
return self.top == self.max_stack - 1
def push(self, val): # 压栈
if self.is_full():
raise StackFullException("your stack is full !!!")
self.stack.append(1)
self.top += 1
# self.stack.insert(self.top, val)
self.stack[self.top] = val
def pop(self