中綴表達式變后綴表達式、后綴表達式(逆波蘭)求值(python版本)


定義:

    中綴表達式: 在通常的表達式中,二元運算符總是置於與之相關的兩個運算對象之間,這種表示法也稱為中綴表達式

    后綴表達式: 又叫逆波蘭表達式 ,不包含括號,運算符放在兩個運算對象的后面,所有的計算按運算符出現的順序,嚴格從左向右進行(不再考慮運算符的優先規則,如:(2 + 1) * 3 , 即2 1 + 3 *

 

一個字符串表達式s = “9 + ( 3 - 1 ) * 3 + 10 / 2”)求值的過程分為兩步

(一) 將 中綴表達式s變為后綴表達式s_after = "9 3 1 - 3 * + 10 2 / +",具體的規則如下 :

     首先維護兩個空棧,(stack_exp)存放逆波蘭表達式,(stack_ops)暫存操作符,運算結束后stack_ops必為空

     循環遍歷字符串(將表達式分為四種元素 1、數值; 2、操作符; 3、 左括號; 4、右括號),具體情況如下

     1、遇到數值, 將該值入棧stack_exp

     2、遇到左括號, 將左括號入棧stack_ops

     3、遇到右括號,將stack_ops中的操作符從棧頂依次出棧並入棧stack_exp, 直到第一次遇到左括號終止操作(注意: 該左括號出棧stack_ops但不入棧stack_exp)至此消除表達式中的一對括號

     4、遇到四則運算操作符號(+ - * /)

          4-1、 如果stack_ops為空, 操作符入棧stack_ops

          4-2、 如果stack_ops不空,將stack_ops棧頂操作符與遍歷到的操作符(op)比較:

               4-2-1: 如果stack_ops棧頂操作符為左括或者op優先級高於棧頂操作符優先級, op入棧stack_ops,當前遍歷結束

               4-2-2: 如果op優先級小於或者等於stack_ops棧頂操作符, stack_ops棧頂操作符出棧並入棧stack_exp,重復4-1、 4-2直到op入棧stack_ops

     5、字符串遍歷結束后如果stack_ops棧不為空,則依次將操作符出棧並入棧stack_exp

     python代碼實現如下:

ops_rule = {
    '+': 1,
    '-': 1,
    '*': 2,
    '/': 2
}

def middle_to_after(s):
    expression = []
    ops = []
    ss = s.split(' ')
    for item in ss:
        if item in ['+', '-', '*', '/']:
            while len(ops) >= 0:
                if len(ops) == 0:
                    ops.append(item)
                    break
                op = ops.pop()
                if op == '(' or ops_rule[item] > ops_rule[op]:
                    ops.append(op)
                    ops.append(item)
                    break
                else:
                    expression.append(op)
        elif item == '(':
            ops.append(item)
        elif item == ')':
            while len(ops) > 0:
                op = ops.pop()
                if op == '(':
                    break
                else:
                    expression.append(op)
        else:
            expression.append(item)

    while len(ops) > 0:
        expression.append(ops.pop())

    return expression
(二) 將后綴表達式s_after = "9 3 1 - 3 * + 10 2 / +" 求值,具體的規則如下 :
初始化一個空棧stack_value,用於存放數值
循環s_after
1、 如果遇到數字,入棧stack_value;
2、 如果遇到運算符, 從stack_value中依次出棧兩個數(先出棧的在右, 后出棧的在左)連同遍歷到的運算符組成二目運算,求值后將結果壓棧stack_value
3、 繼續遍歷下一個元素,直到結束
遍歷完后stack_value中的結果便是表達式的值
python代碼實現如下:
def expression_to_value(expression):
    stack_value = []
    for item in expression:
        if item in ['+', '-', '*', '/']:
            n2 = stack_value.pop()
            n1 = stack_value.pop()
            result = cal(n1, n2, item)
            stack_value.append(result)
        else:
            stack_value.append(int(item))
    return stack_value[0]

def cal(n1, n2, op):
    if op == '+':
        return n1 + n2
    if op == '-':
        return n1 - n2
    if op == '*':
        return n1 * n2
    if op == '/':
        return n1 / n2


if __name__ == '__main__':
    expression = middle_to_after('9 + ( 3 * ( 4 - 2 ) ) * 3 + 10 / 2')
    value = expression_to_value(expression)
    print value
 
        

  

 

 

 








               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM