python 栈实现简单计算

今日学习了栈,栈的主要应用就是实现求解表达式,我们首先来理解一下栈求解表达式的原理:
栈的原理是先进来的先出去:
python 栈实现简单计算_第1张图片
(上面为手绘,丑陋莫要建议,嘻嘻)进去的顺序为a,b,c,出来的顺序为c,b,a

中缀转后缀原理:
遇到数字放一边,遇到符号入栈,入栈规则是:如果栈顶的符号的优先级小于目标优先级,则目标优先级入栈:
python 栈实现简单计算_第2张图片
求解原理:首先将后缀表达式按顺序入栈,符号出栈,计算符号下面的两个数并将结果入栈,最后留下的数字是求解结果
python 栈实现简单计算_第3张图片
python代码:


```python
# 用python实现ADT Stack
class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(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)


# 中缀转后缀
def InToPost(infix):
    prec = {}
    prec['('] = 0 #此处
    prec['^'] = 3
    prec['*'] = 2
    prec['/'] = 2
    prec['+'] = 1
    prec['-'] = 1  # 确定运算符的优先级
    infixitem = infix.split()  # 将中缀分割,注意此处默认是空格分隔
    print(infixitem)
    signStack = Stack()  # 定义一个空栈放入运算符
    postlist = []  # 定义一个空列表放后缀字符
    for item in infixitem:
        if item not in  "+-*/^()":  # 将运算内容放入列表
            postlist.append(item)

        elif item == '(':
            signStack.push(item)
        elif item == ')':  # 括号匹配
            topitem = signStack.pop()
            while topitem != '(':
                postlist.append(topitem)
                topitem = signStack.pop()
        else:
            while not (signStack.isEmpty()) and (prec[item] <= prec[signStack.peek()]) :
                postlist.append(signStack.pop())
            signStack.push(item)
    while not signStack.isEmpty():
        postlist.append(signStack.pop())
    return postlist  # 合成后缀表达式字符串


# 后缀表达式求值
def postsolve(postlist):
    stack_ = Stack()
    for item in postlist:
        if item  not in "+-*/^()":
            stack_.push(int(item))
        else:
            operand2 = stack_.pop()
            operand1 = stack_.pop()
            result = domath(item, operand1, operand2)
            stack_.push(result)
    return stack_.pop()


# domath函数
def domath(item, operand1, operand2):
    if item == '*':
        return operand1 * operand2
    elif item == '/':
        return operand1 / operand2
    elif item == '+':
        return operand1 + operand2
    elif item == '^':
        return operand1 ** operand2
    else:
        return operand1 - operand2


# 验证代码
print("please input the express:")
express = "3 + 46 * ( 7 - 1 ) * 23"
a = InToPost(express)
print(a)
postsolve(InToPost(express))
print("the result is equal to {}".format( postsolve(InToPost(express))))

上面的代码有一个地方需要主要一下,就是优先级赋值那一块,我将“(”的赋值为0按优先级来讲是不对的,但是我的目的是如果运算符遇到’(‘为栈顶,可以直接入栈,不要比较,因为如果比较的话,一定是’(‘优先级高,那么’(‘就会出栈,引起错误,其实读者可将后面的条件加上如果top != ’(‘这一条件。

你可能感兴趣的:(python,算法,栈,数据结构)