• Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算


    中缀表达式与后缀表达式的转换和计算


    目录

    1. 中缀表达式转换为后缀表达式
    2. 后缀表达式的计算

    1 中缀表达式转换为后缀表达式

    中缀表达式转换为后缀表达式的实现方式为:

    1. 依次获取中缀表达式的元素,
    2. 若元素为操作数(数字/字母等),则加入后缀表达式中
    3. 若元素为操作符,则压入栈中,此时对比入栈操作符与栈内元素的计算等级,等级大于或等于入栈元素的栈内操作符都将被弹出栈,加入到后缀表达式中
    4. 左括号直接入栈,优先级最高,不弹出栈内元素
    5. 右括号不入栈,而是弹出所有元素加入后缀表达式,直至遇见匹配的左括号,并弹出左括号但不加入后缀表达式中
    6. 当中缀表达式的元素耗尽后,依次弹出栈内元素加入到后缀表达式中。

    代码实现过程如下,

    完整代码

     1 from linked_list_stack import Stack
     2 
     3 SIGN = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3}
     4 
     5 
     6 def infix_to_postfix(expr):
     7     global SIGN
     8     out = []
     9     s = Stack()
    10     for i in expr:
    11         if i in SIGN.keys():
    12             # Pop all high level sign except left bracket
    13             while s.top():
    14                 if SIGN[s.top()] < SIGN[i] or s.top() == '(':
    15                     break
    16                 out.append(s.pop())
    17             # Push sign
    18             s.push(i)
    19         elif i == ')':
    20             # Pop all sign until left bracket encountered
    21             while s.top() != '(':
    22                 out.append(s.pop())
    23             # Pop left bracket
    24             s.pop()
    25         else:
    26             # Push number
    27             out.append(i)
    28 
    29     while s.top():
    30         out.append(s.pop())
    31     return out
    32 
    33 
    34 if __name__ == '__main__':
    35     ep = 'a + b * c + ( d * e + f ) * g'
    36     print(' '.join(infix_to_postfix(ep.split(' '))))
    View Code

    分段解释

    首先从链表栈中导入栈类,并定义各个操作符的优先级

    1 from linked_list_stack import Stack
    2 
    3 SIGN = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3}

    接着定义转换函数,

    1. 函数接受一个中缀表达式的可迭代对象,创建列表out存放后缀表达式,以及一个空栈s
    2. 随后开始遍历中缀表达式,判断遍历元素的类型,若为操作数则加入out,
    3. 若为右括号则依次弹出栈内元素加入out列表,直到遇见左括号,弹出左括号不加入out,
    4. 若为普通操作符则压入栈中,并对比栈内操作符优先级,依次弹出高优先级或相同优先级的操作符,
    5. 遍历结束后依次弹出栈内元素,最后返回后缀表达式的字符串形式。
     1 def infix_to_postfix(expr):
     2     global SIGN
     3     out = []
     4     s = Stack()
     5     for i in expr:
     6         if i in SIGN.keys():
     7             # Pop all high level sign except left bracket
     8             while s.top():
     9                 if SIGN[s.top()] < SIGN[i] or s.top() == '(':
    10                     break
    11                 out.append(s.pop())
    12             # Push sign
    13             s.push(i)
    14         elif i == ')':
    15             # Pop all sign until left bracket encountered
    16             while s.top() != '(':
    17                 out.append(s.pop())
    18             # Pop left bracket
    19             s.pop()
    20         else:
    21             # Push number
    22             out.append(i)
    23 
    24     while s.top():
    25         out.append(s.pop())
    26     return out
    27 
    28 
    29 if __name__ == '__main__':
    30     ep = 'a + b * c + ( d * e + f ) * g'
    31     print(' '.join(infix_to_postfix(ep.split(' '))))

    最后可以得到表达式输出结果为

    a b c * + d e * f + g * +

    2 后缀表达式的计算

    后缀表达式的计算过程其实也是后缀转换为中缀的一个过程:

    1. 首先依次遍历后缀表达式,
    2. 当元素为操作数时,压入栈中,
    3. 当元素为操作符时,弹出栈内最顶上的两个元素,进行操作运算,将得到的结果再次压入栈中,
    4. 直到后缀表达式遍历结束,此时栈内只有唯一的一个元素即最终的运算结果,弹出栈即可

    实现的过程十分简单,具体代码如下,其中中缀表达式转后缀表达式的方法为前面定义的方法

    完整代码

     1 from linked_list_stack import Stack  
     2   
     3 SIGN = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3}  
     4   
     5   
     6 def postfix_calc(expr):  
     7     global SIGN  
     8     s = Stack()  
     9     for i in expr:  
    10         if i in SIGN.keys():  
    11             right = str(s.pop())  
    12             left = str(s.pop())  
    13             cal = ' '.join((left, i, right))  
    14             # cal = ' '.join([str(s.pop()), i, str(s.pop())][::-1])  
    15             s.push(eval(cal))  
    16         else:  
    17             s.push(i)  
    18     return s.pop()  
    19   
    20 if __name__ == '__main__':  
    21     ep = '( ( 2 + 3 ) * 8 + 5 + 3 ) * 6'  
    22     print(eval(ep))  
    23     print(postfix_calc(infix_to_postfix(ep.split(' '))))  
    24   
    25     ep = '3 + ( 2 * 9 ) / 2 * ( 3 + 6 ) * 7'  
    26     print(eval(ep))  
    27     print(postfix_calc(infix_to_postfix(ep.split(' '))))  

    最后测试直接运算中缀表达式和中缀转后缀后再计算得到的结果,两者结果相同。

    288
    288
    570.0
    570.0
  • 相关阅读:
    vmware虚拟机Linux(redhat)上用户密码忘记了怎么办?
    redis常见数据类型操作命令
    spring boot自动配置原理
    linux使用xshell连接linux教程
    KafkaRebalance
    kafkaconnect研究
    Kafkarestproxy
    Window Nacos 单机配置与启动
    iptables控制
    在c/c++中输入彩色日志输出,带有带有颜色的打印
  • 原文地址:https://www.cnblogs.com/stacklike/p/8284594.html
Copyright © 2020-2023  润新知