实现计算器功能(中缀表达式转为后缀表达式进行计算)【python】

实现计算器功能(python)

编译程序时一般都使用后缀表达式进行计算。那什么是后缀表达式呢?
任何一个表达式都可以由操作数、操作符、分解符组成。通常,算数表达式有3中表示:

  • 中缀(infix)表示 : <操作数><操作符><操作数>,例如A+B
  • 后缀(postfix)表示 : <操作数><操作数><操作符>,例如AB+
  • 前缀(prefix)表示 : <操作符><操作数><操作数>,例如+AB

一般利用栈来实现后缀表达式的计算。当遇到操作数时,压栈;当遇到操作符时,弹出两个操作数进行计算,将结果压栈。

实现计算器功能,分两步:

  1. 中缀表达式变为后缀表达式
  2. 利用栈进行后缀表达式计算

中缀表达式变为后缀表达式

在进行计算时,要进行优先级的比较。
isp(in stack priority)栈内优先数
icp(in coming priority)栈外优先数

操作符 # ( * / % + - )
isp 0 1 5 3 6
icp 0 6 4 2 1

算法描述:

  1. 操作符初始,将结束符#入栈,读取字符流s
  2. 重复步骤,当字符流结束且栈到结束符,停止循环
    a. 若s是操作数,直接输出,读取下一个s
    b. 若s是操作符,栈顶用op表示:
    • 若icp(s) > isp(op): s进栈,读取下一个字符
    • 若icp(s) < isp(op): 退栈并输出
    • 若icp(s) == isp(op): 退栈但不输出,若op == “(”,读取下一个字符
  3. 算法结束,输出即后缀表达式

代码如下

def infix2postfix(ss):
    res = []
    stack = ["#"]
    isp = {
    
    "+":3,"-":3,"*":5,"/":5,"(":1,")":6,"#":0}
    icp = {
    
    "+":2,"-":2,"*":4,"/":4,"(":6,")":1,"#":0}
    ss = ss.split()
    i = 0
    while i < len(ss):
        if ss[i].isdigit():
            res.append(ss[i])
            i += 1
        else:
            if isp[stack[-1]]<icp[ss[i]]:
                stack.append(ss[i])
                i += 1
            elif isp[stack[-1]]>icp[ss[i]]:
                res.append(stack.pop())
            else:
                stack.pop()
                i += 1
    while stack[-1] != "#":
        res += stack.pop()
    return res

利用后缀表达式进行计算

完整代码

def infix2postfix(ss):
    res = []
    stack = ["#"]
    isp = {
    
    "+":3,"-":3,"*":5,"/":5,"(":1,")":6,"#":0}
    icp = {
    
    "+":2,"-":2,"*":4,"/":4,"(":6,")":1,"#":0}
    ss = ss.split()
    i = 0
    while i < len(ss):
        if ss[i].isdigit():
            res.append(ss[i])
            i += 1
        else:
            if isp[stack[-1]]<icp[ss[i]]:
                stack.append(ss[i])
                i += 1
            elif isp[stack[-1]]>icp[ss[i]]:
                res.append(stack.pop())
            else:
                stack.pop()
                i += 1
    while stack[-1] != "#":
        res += stack.pop()
    return res

def calculate(ss):
    stack = []
    for item in ss:
        if item.isdigit():
            stack.append(int(item))
        else:
            right = stack.pop()
            left = stack.pop()
            if item == "+":
                ans = left + right
            elif item == "-":
                ans = left - right
            elif item == "*":
                ans = left * right
            elif item == "/":
                ans = left / right
            stack.append(ans)
    return stack[0]

结果

ss = "9 + 10 / 2 - 4 / ( 6 + 6 )"
ss = infix2postfix(ss)
ans = calculate(ss)
# 13.666666666666666

猜你喜欢

转载自blog.csdn.net/qq_40840633/article/details/101060350