栈的特点

栈是限定仅在表尾进行插入和删除操作的线性表。允许插入与删除的一段叫做栈顶,另一端叫做栈底,不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。

  • 可以用列表来实现栈
list = [4]
#相当于压栈
list.append(6)
print(list)
>>>[4,6]
#相当于弹栈
list.pop()
print(list)
>>>[4]

一、中缀表达式转化为后缀表达式

规则:从左到右遍历中缀表达式中的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号则要分为两种情况:

1)是括号时,如果是左括号,直接将左括号入栈,如果是右括号则栈顶元素依次出栈并输出,直到有一个左括号出栈(出栈的左括号不输出到后缀表达式)。

2)是运算符号时,如果栈顶符号为左括号,则直接将这个运算符号入栈。栈顶符号不为左括号时,如果该运算符号优先级比栈顶运算符号高则入栈,比栈顶符号低或者相等时则栈顶元素依次出栈并输出直到栈为空或者栈顶为左括号为止,然后将这个符号入栈。

最后将栈顶符号依次出栈并输出,得到的结果即为最终的后缀表达式。

实现代码如下:

# 转为后缀表达式,运算表达式元素之间用空格隔开:
def change_opt(opt):
    result = []  #结果列表
    stack = []  # 栈
    item_lists = opt.split(' ')
    for item in item_lists:
        # 如果当前字符为整数或者小数那么直接放入结果列表
        if item.isdigit() or '.' in item:
            result.append(item)
        else:
            if len(stack) == 0:     # 如果栈空,直接入栈
                stack.append(item)
            elif item in '*/(':     # 如果当前字符为*/(,直接入栈
                stack.append(item)
            elif item == ')':
                t = stack.pop()
                while t != '(':
                    result.append(t)
                    t = stack.pop()
            elif item in '+-' and stack[-1] in '*/':
                if stack.count('(') == 0:
                    while stack:
                        result.append(stack.pop())
                else:  # 如果有左括号,输出到左括号为止
                    t = stack.pop()
                    while t != '(':
                        result.append(t)
                        t = stack.pop()
                    stack.append('(')
                stack.append(item)
            else:
                stack.append(item)
    #把栈中数据弹出
    while stack:
        result.append(stack.pop())
    return result

二、后缀表达式计算

规则:从左到右遍历表达式的每个数字和符号,遇到的是数字就进栈,遇到的时符号就将栈顶的两个数字出栈进行计算,然后将计算结果入栈,最终栈里的值即为计算的结果。

1.遍历表达式

代码如下(示例):

#后缀表达式计算
def get_value(follow):
    num = []
    base_opt = ['+', '-', '*', '/']
    # print(follow)
    for j in follow:
        if j.isdigit() or '.' in j:
            num.append(float(j))
        if j in base_opt:
            num2 = num.pop()
            num1 = num.pop()
            res=method(num1,num2,j)
            num.append(res)
    return num[0]

2.计算方法

代码如下(示例):

def method(num1,num2,j):
    if j == "+":
        res=num1 + num2
    elif j == "-":
        res=num1 - num2
    elif j == "*":
        res=num1 * num2
    else:
        res=num1 / num2
    return res

完整代码

# 转为后缀表达式,运算表达式元素之间用空格隔开:
def change_opt(opt):
    result = []  #结果列表
    stack = []  # 栈
    item_lists = opt.split(' ')
    for item in item_lists:
        # 如果当前字符为整数或者小数那么直接放入结果列表
        if item.isdigit() or '.' in item:
            result.append(item)
        else:
            if len(stack) == 0:     # 如果栈空,直接入栈
                stack.append(item)
            elif item in '*/(':     # 如果当前字符为*/(,直接入栈
                stack.append(item)
            elif item == ')':
                t = stack.pop()
                while t != '(':
                    result.append(t)
                    t = stack.pop()
            elif item in '+-' and stack[-1] in '*/':
                if stack.count('(') == 0:
                    while stack:
                        result.append(stack.pop())
                else:  # 如果有左括号,输出到左括号为止
                    t = stack.pop()
                    while t != '(':
                        result.append(t)
                        t = stack.pop()
                    stack.append('(')
                stack.append(item)
            else:
                stack.append(item)
    #把栈中数据弹出
    while stack:
        result.append(stack.pop())
    return result

#后缀表达式计算
def get_value(follow):
    num = []
    base_opt = ['+', '-', '*', '/']
    # print(follow)
    for j in follow:
        if j.isdigit() or '.' in j:
            num.append(float(j))
        if j in base_opt:
            num2 = num.pop()
            num1 = num.pop()
            res=method(num1,num2,j)
            num.append(res)
    return num[0]

def method(num1,num2,j):
    if j == "+":
        res=num1 + num2
    elif j == "-":
        res=num1 - num2
    elif j == "*":
        res=num1 * num2
    else:
        res=num1 / num2
    return res

if __name__ == '__main__':
	#空格隔开,括号注意中英文不要乱
    opt = "9 + ( 3 - 1 ) * 3 + 10 / 2"
    result=change_opt(opt)
    print(get_value(result))

学习:https://blog.csdn.net/qq_42842335/article/details/84678929

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐