使用栈实现计算表达式的思路:
- 通过一个index值,来遍历我们的表达式
- 如果我们发现扫描的是一个数字,就直接入数字栈
- 如果我们发现扫描的是一个符号,就分如下的情况
- 如果发现当前的符号栈为空,就直接入栈
- 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数字栈中pop出两个数,在符号栈中pop出一个符号,进行运算,将得到的结果,入数栈,然后将当前的操作符入符号栈,如果当前的操作符的优先级大于栈中的操作符,就直接如符号栈
- 当表达式扫描完毕,就书序的从数栈和符号栈中pop出相应地数和符号,并运行
- 最后在数栈只有一个数字,就是表达式的结果
class ArrayStack2:
def __init__(self,masSize):
self.maxsize = masSize
self.stack = []
self.top = -1
# 判断栈是不是 满的
def isFull(self):
return self.top == self.maxsize - 1
# 判断栈是不是空的
def isEmpty(self):
return self.top == -1
# 将数据压入栈中
def push(self,value):
if self.isFull():
print("栈已经满了!")
return
self.top = self.top + 1
self.stack.append(value)
# 将栈中的数据进行删除
def pop(self):
if self.isEmpty():
print("栈已经是空的了,没法执行出栈操作!")
return
value = self.stack.pop()
self.top = self.top - 1
return value
# 显示栈的内容,需要先从栈顶显示数据
def showStack(self):
if self.isEmpty():
print("栈已经是空的了,没法执行显示操作!")
return
i = self.top
while i > -1:
print("栈中存在的数据:",self.stack[i])
i = i -1
# 返回运算法的优先级 有程序员决定 优先级使用数字来表示,数字越大优先级越高
def priority(self,oper):
if (oper == "*" or oper == "/"):
return 1
elif (oper == "+" or oper == "-"):
return 0
else:
return -1
# 判断是不是一个运算法
def isOper(self,val):
return val == "*" or val == "/" or val == "+" or val =="-"
# 进行计算
def cal(self,num1,num2,oper):
if oper == "+":
return num1 + num2
elif oper == "-":
return num2 - num1 # 注意顺序
elif oper == "*":
return num1 * num2
elif oper == "/":
return num2 / num1
# 只返回最后的一个元素,但是并不是删除最后 一个元素
def peek(self):
return self.stack[self.top]
class Calculator:
def __init__(self,expresion = "30+2*6-22"):
self.expresion = expresion
# 创建两个栈 一个数字栈,一个符号栈
self.numstack1 = ArrayStack2(10)
self.operstack2 = ArrayStack2(10)
self.num1 = 0
self.num2 = 0
self.oper = 0
self.res = 0
self.keepnum = ""
self.flag = 0 # 作为多位数的标志位
self.index = 1 # 用于检查每个数字字符串后面是不是还有字符串
def cal1(self):
data = 0
while data < len(self.expresion):
#for data in range(len(self.expresion)):
print(self.expresion[data])
if self.expresion[data] == " ": # 因为有时候会产生空格
continue
if self.operstack2.isOper(self.expresion[data]):
if self.operstack2.isEmpty():
# 直接入栈
self.operstack2.push(self.expresion[data])
# 如果不为空,就有其他操作,就是比较运算法的优先级
else:
if (self.operstack2.priority(self.expresion[data]) <= self.operstack2.priority(self.operstack2.peek())):
# 此时从数栈中取出来两个数,然后进行计算
self.num1 = self.numstack1.pop()
self.num2 = self.numstack1.pop()
self.oper = self.operstack2.pop()
self.res = self.numstack1.cal(self.num1,self.num2,self.oper)
self.numstack1.push(self.res)
self.operstack2.push(self.expresion[data])
else:
# 如果当前的优先级大于栈中的运算符
self.operstack2.push(self.expresion[data])
else:
self.keepnum = self.expresion[data]
while True:
if data + self.index <= len(self.expresion) - 1:
if (self.operstack2.isOper(self.expresion[data+self.index])) == False:
self.flag = 1
self.keepnum = self.keepnum + self.expresion[data+self.index]
self.index = self.index + 1
else:
break
else:
break
self.numstack1.push(int(self.keepnum))
self.keepnum = ""
#self.numstack1.push(int(self.expresion[data]))
if self.flag:
data =data + self.index
self.index = 1
self.flag = 0
else:
data = data + 1
print("看看数字栈中的数:", self.numstack1.showStack())
while True:
if self.operstack2.isEmpty():
break
self.num1 = self.numstack1.pop()
self.num2 = self.numstack1.pop()
self.oper = self.operstack2.pop()
self.res = self.numstack1.cal(self.num1, self.num2,self.oper)
self.numstack1.push(self.res)
print("看看数字栈中最后的的数:",self.numstack1.showStack())
print(self.numstack1.pop())
if __name__ == '__main__':
cal = Calculator()
cal.cal1()