栈的应用(3)——中缀表达式转后缀表达式并求值 python实现

引言

输入运算表达式,仅由数字、+、-、*、/、()组成,没有空格,要求求其值,

中缀表达式:通常看到的表达式中,操作符介于操作数中间的表示法,如A+B,BC,A+BC(容易混淆)。为了避免混淆,引入优先级或者括号来定义顺序。(A+B)C
前缀表达式:将操作移动到前面的表示法,如+AB, * +ABC
后缀表达式:将操作移动到后面的表示法,如AB+,AB+C

因此,(A+B)*C转化为AB+C *和 * +ABC时括号消失,因此可将中缀表达式转化为前缀或者后缀,消除运算的次序,不在有混淆。

1.通用的中缀转后缀算法原理

从左到右扫描后缀表达式
1.若是操作数,就压栈,直接添加到后缀表达式列表的末尾。
2.若是左括号“(”,则压入栈顶,若是“)”,则反复弹出栈顶操作符,加入到输出列表末尾,直到碰到左括号
2.若是操作符,“*/±”,则压入栈顶,并连续弹出两个操作数,根据操作符计算两个操作数,最后把计算结果再次压到栈顶,
3.栈顶的值即为计算最终结果
输出后缀过程:
在这里插入图片描述

2.通用中缀转后缀算法实现

2.1 定义栈及其属性

class Stack(object):   #定义栈 属性
    """栈"""
    def __init__(self):
         self.items = []

    def is_empty(self):
        """判断是否为空"""
        return self.items == []

    def push(self, item):
        """加入元素"""
        self.items.append(item)

    def pop(self):
        """弹出元素"""
        return self.items.pop()

    def peek(self):
        """返回栈顶元素"""
        return self.items[len(self.items)-1]

    def size(self):
        """返回栈的大小"""
        return len(self.items)

2.2 中缀转后缀代码

def infixtopostfix(infixexpr):  ## 通用中缀表达式转化为后缀表达式
    prec={}          #记录操作符优先级
    prec["*"]=3
    prec["/"]=3
    prec["+"]=2
    prec["-"]=2
    prec["("]=1

    opstack=Stack()
    postfixlist=[]
    tokenlist=infixexpr.split()      #解析式转换为单词列表
        for token in tokenlist:
        if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
            postfixlist.append(token)
        elif token=='(':
            opstack.push(token)
        elif token==')':
            toptoken=opstack.pop()
            while toptoken !='(':
                postfixlist.append(toptoken)
                toptoken=opstack.pop()
        else:    ##操作符
            while (not opstack.is_empty()) and \
                    (prec[opstack.peek()]>=prec[token]):
                postfixlist.append(opstack.pop())
                opstack.push(token)

    while not opstack.is_empty():     #返回后缀表示式字符串
        postfixlist.append(opstack.pop())
    return postfixlist

注:此处输出表示式字符串为空,后续修正

3. 后缀表达式求值

3.1 求值过程原理
(1)创建空栈用于暂存操作数
(2)将后缀表达式用split方法解析为单词token的列表
(3)从左到右扫描单词列表
(a)若单词为操作数,将单词转为整型int,压入栈顶
(b)若单词为操作符,就从栈顶弹出两操作符并计算其值,压入栈顶
(4)单词列表扫描完后,表达式的值就在栈顶,弹出并返回。

3.2 算法过程实现

def postfieval(postfixexpr):
    operandstack=Stack()
    tokenlist=postfixexpr.split()

    for token in tokenlist:
        if token in "0123456789":
            operandstack.push(int(token))
        else:
            operand2=operandstack.pop()
            operand1=operandstack.pop()
            result=domath(token,operand1,operand2)
            operandstack.push(result)

    return operandstack.pop()
def domath (op,op1,op2):
    if op =="*":
        return op1*op2
    elif op =="/":
        return op1/op2
    elif op == "+":
        return op1+op2
    else:
        return op1-op2

最后要问的是有没有人知道转换过程中输出为空,我的代码在哪里出了bug?请在下面留言,感激不尽~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨猪起飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值