计算表达式的的值是栈的应用,比如我们求中缀表达式(A+B*(C-D)-E/F)的值,
1.首先需要将它去掉括号,转化为后缀表达式ABCD-*+EF/-
2.依次扫描后缀表达式的值,如果是数字入栈,遇到运算符则弹出两个数,和运算符运算后再入栈……最后栈顶就是结果
给出python代码如下:
class LinkNode:
def __init__(self,**kw):
self.data=kw["data"]
self.next=kw["next"]
class LinkStack:
def __init__(self):
self.head=LinkNode(data=None,next=None)
def Push(self,data):
node=LinkNode(data=data,next=None)
node.next=self.head.next
self.head.next=node
def Pop(self):
if not self.IsEmpty():
data=self.head.next.data
self.head.next= self.head.next.next
return data
else:
return None
def IsEmpty(self):
if self.head.next==None:
return True
else:
return False
def GetTop(self):
if not self.IsEmpty():
return self.head.next.data
else:
return None
class Suffix:
def __init__(self,str):
self.str=str.replace(" ", "")
self.stack=LinkStack()
self.expression=""
self.level={"(":0,
")": 0,
"*": 2,
"/": 2,
"+": 1,
"-": 1,
}
def GetSuffix(self):
for i in self.str:
if i=="(":
self.stack.Push(i)
elif i==")":
while not self.stack.IsEmpty():
j=self.stack.Pop()
if j!="(":
self.expression=self.expression+str(j)
else:
break
elif i in ("+","-","*","/"):
if not self.stack.IsEmpty():
top=self.stack.GetTop()
if self.level[i]>self.level[top]:
self.stack.Push(i)
else:
while not self.stack.IsEmpty() and self.level[self.stack.GetTop()]>=self.level[i] and self.stack.GetTop()!="(":
j=self.stack.Pop()
self.expression = self.expression + str(j)
self.stack.Push(i)
else:
self.stack.Push(i)
else:
self.expression = self.expression + str(i)
while not self.stack.IsEmpty():
j = self.stack.Pop()
self.expression = self.expression + str(j)
def getExpressionValue(expression):
stack=LinkStack()
for i in expression:
if i.isdigit():
stack.Push(int(i))
else:
n=stack.Pop()
m=stack.Pop()
j=eval(str(m)+i+str(n))#这个要是不用eval就得用补码反码算二进制数了
print(str(m)+i+str(n),"=",j)
stack.Push(int(j))
return stack.GetTop()
if __name__=="__main__":
suffix=Suffix("8/2+(3*6+4*8)/5")
#可以改成别的
suffix.GetSuffix()
expression=suffix.expression
print("后缀表达式:",expression)
value=getExpressionValue(expression)
print("结果",value)
其中
suffix=Suffix("8/2+(3*6+4*8)/5")
#可以改成别的
suffix.GetSuffix()
expression=suffix.expression
这个传入中缀,传出后缀
如果是数字字符呢
上面的代码不能解决的问题有
1.如果是两位数,比如20,就出现了问题,上面的代码会认为是字符2和字符0
2.如果是小数,比如1.1,也会有问题,会按顺序拆成三个字符
3.如果数前面有负号,负号会当作运算符
4.两个数的运算实际是用的eval函数,其实有点作弊了,何不用eval处理整个字符串表达式,如果自己写浮点数运算,则要回到组成原理了
解决方法也有,但是我懒得改了
1.将表达式用正则处理,将数存入节点的value中,后面循环节点数组而不是字符串。如果不用正则,则要一个个输入字符,或者用队列处理字符串,将数字和运算符分出来
2.浮点数的加减乘除可以参考我这篇文章https://blog.csdn.net/qq_34153210/article/details/107024323
那么上面的代码岂不是没有什么卵用,Suffix类还是可以看看,其它的确实没有什么卵用
另附上链队的python表示
#也可以用两个栈来实现队列
class LinkNode:
def __init__(self,**kw):
self.data=kw["data"]
self.next=kw["next"]
class LinkQueue:
def __init__(self):
self.HeadNode =LinkNode(data=None,next=None)
self.front = self.HeadNode
self.rear = self.HeadNode
def IsEmpty(self):
if (self.front == self.rear):
return True
else:
return False
#入队
def EnQueue(self,value):
Lnode = LinkNode(data=None,next=None)
Lnode.data = value
Lnode.next = None
self.rear.next = Lnode
self.rear = Lnode
#出队
def DeQueue(self):
if (self.front == self.rear):
return False
p = self.front.next
value = p.data
self.front.next = p.next
if (p == self.rear):
self.rear = self.front
return value