计算表达式的值

计算表达式的的值是栈的应用,比如我们求中缀表达式(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

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值