当前位置 博文首页 > python利用后缀表达式实现计算器功能

    python利用后缀表达式实现计算器功能

    作者:ikalpa 时间:2021-07-25 11:47

    本文实例为大家分享了python实现计算器功能的具体代码,供大家参考,具体内容如下

    前缀表达式

    运算符在数字的前面

    1 + (2 + 3) * 4 - 5 (中缀)
    - + 1 * + 2 3 4 5  (前缀)

    前缀表达式的计算方法和后缀表达式类似,只是变成了从右往左扫描

    中缀表达式

    运算符在中间,运算时需要考虑运算符优先级

    1+2*3-5
    要先算2*3....

    后缀表达式

    运算符在数字的后面,运算时不考虑优先级,只需要遇到符号,就把他前面的两个数字进行运算就好了

    例如: a b c + + 即: a + (b + c)

    1 + (2 + 3) * 4 - 5 (中缀)
    1 2 3 + 4 * + 5 -  (后缀)

    因为无需考虑优先级,运算是线性结构的,其用栈实现会很简单

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

    运算规律,运算数位置不变,改变的是符号的位置

    2 + 9 / 3 - 5   (中缀)
    2 9 3 / + 5 -  (后缀)

    具体方式

    1.从左到右进行遍历
    2.运算数,直接输出.
    3.左括号,直接压入堆栈,(括号是最高优先级,无需比较)(入栈后优先级降到最低,确保其他符号正常入栈)
    4.右括号,(意味着括号已结束)不断弹出栈顶运算符并输出直到遇到左括号(弹出但不输出)
    5.运算符,将该运算符与栈顶运算符进行比较,
    如果优先级高于栈顶运算符则压入堆栈(该部分运算还不能进行),
    如果优先级低于等于栈顶运算符则将栈顶运算符弹出并输出,然后比较新的栈顶运算符.
    (低于弹出意味着前面部分可以运算,先输出的一定是高优先级运算符,等于弹出是因为同等优先级,从左到右运算)
    直到优先级大于栈顶运算符或者栈空,再将该运算符入栈.
    **6.*如果对象*处理完毕,则按顺序弹出并输出栈中所有运算符.

    后缀表达式运算步骤

    后缀表达式运算步骤:

    (以堆栈储存)
    从左到右,遇到运算符就弹出相应的运算数,运算后再把结果入栈.最终结果就是栈顶数的值.
    (由于该运算为线性结构,具体运算时是不需要储存输出后的运算符,一般是输出一个运算符就进行一次运算,不像图中要储存输出状态.)

    注意点:

    有时候'-'(负号)是单目运算符,则要修改运算数.
    遇到其他运算符(如幂运算)也类似.

    python代码例子

    '''
    中缀转换为后缀
    '''
    
    a = "1+(2+6/1+2)"
    #a = "2+9/3-5"
    # 可能出现的符号 
    symbol_1 = ['+','-','*','/']
    symbol_2 = ['(']
    symbol_3 = [')']
    # 符号的优先级
    priority = {'#':-1,'(':1,'+':2,'-':2,'*':3,'/':3}
    match_2 = {')':'('}
    # 存储符号的栈
    zhan = []
    zhan.append("#")
    # 结果
    result = []
    
    '''
    ### 这里只是对表达式进行转换
    for i in a:
     # 如果是数字直接添加到结果
     if i.isdigit():
     result.append(i)
     # 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈
     elif i in symbol_1:
     # 如果优先级低,则出栈所有优先级>=的符号
     while priority[i] <= priority[zhan[-1]]:
     result.append(zhan.pop())
     # 压入符号
     zhan.append(i)
     # 如果是左括号,直接压入
     elif i in symbol_2:
     zhan.append(i)
     # 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈
     elif i in symbol_3:
     while zhan[-1] != match_2[i]:
     result.append(zhan.pop())
     zhan.pop()
     
    result.append(zhan.pop())
    print(''.join(result))
    
    '''
    # 下面通过将中缀表达式转换为后缀表达式,并进行运算
    def my_operation(symbol, a, b):
     a,b = int(a),int(b)
     if symbol == '+':
     return a + b
     elif symbol == '-':
     return a - b
     elif symbol == '*':
     return a * b
     elif symbol == '/':
     return a / b
    
    def to_operation(result, zhan):
     two = result.pop()
     one = result.pop()
     symbol = zhan.pop()
     ret = my_operation(symbol, one, two)
     print(f"{one}{symbol}{two} = {ret}")
     result.append(ret)
    
    ### 在表达式转换的时候就一边进行了运算
    for i in a:
     # 如果是数字直接添加到结果
     if i.isdigit():
     result.append(i)
     # 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈
     elif i in symbol_1:
     # 如果优先级低,则出栈所有优先级>=的符号
     while priority[i] <= priority[zhan[-1]]:
     to_operation(result, zhan)
     # 压入符号
     zhan.append(i)
     # 如果是左括号,直接压入
     elif i in symbol_2:
     zhan.append(i)
     # 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈
     elif i in symbol_3:
     while zhan[-1] != match_2[i]:
     to_operation(result, zhan)
     zhan.pop()
     
    to_operation(result, zhan)
    print(result)
    jsjbwy