【python】利用栈实现四则运算表达式求值,附代码


栈的特点

栈是限定仅在表尾进行插入和删除操作的线性表。允许插入与删除的一段叫做栈顶,另一端叫做栈底,不含任何数据元素的栈称为空栈。栈又称为后进先出(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

  • 10
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
四则运算表达式习题是指通过的数据结构来进行四则运算的练习题。其中包括中缀表达式转后缀表达式和后缀表达式的计算。首先,中缀表达式转后缀表达式是通过使用的特点,将中缀表达式转化为等价的后缀表达式。然后,利用后缀表达式进行计算时,需要遍历表达式,按照计算方法进行计算。以下是一个完整的示例代码,用于演示四则运算表达式习题: ```python # 定义函数,用于判断运算符的优先级 def precedence(operator): if operator == '+' or operator == '-': return 1 elif operator == '*' or operator == '/': return 2 else: return 0 # 定义函数,用于将中缀表达式转化为后缀表达式 def infix_to_postfix(expression): stack = [] postfix = '' for char in expression: if char.isdigit(): postfix += char elif char == '(': stack.append(char) elif char == ')': while stack and stack[-1 != '(': postfix += stack.pop() stack.pop() else: while stack and precedence(char) <= precedence(stack[-1]): postfix += stack.pop() stack.append(char) while stack: postfix += stack.pop() return postfix # 定义函数,用于计算后缀表达式 def evaluate_postfix(expression): stack = [] for char in expression: if char.isdigit(): stack.append(int(char)) else: num2 = stack.pop() num1 = stack.pop() if char == '+': stack.append(num1 + num2) elif char == '-': stack.append(num1 - num2) elif char == '*': stack.append(num1 * num2) elif char == '/': stack.append(num1 / num2) return stack.pop() # 示例表达式 infix_expression = '(3+4)*(5-2)' postfix_expression = infix_to_postfix(infix_expression) result = evaluate_postfix(postfix_expression) # 输出结果 print("中缀表达式:", infix_expression) print("后缀表达式:", postfix_expression) print("计算结果:", result) ``` 以上代码会将中缀表达式"(3+4)*(5-2)"转化为后缀表达式"34+52-*",并且计算出结果为21。这是四则运算表达式习题的一个例子。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值