Python计算器之逆波兰实现

# -*- coding: utf-8 -*
import re

def fmt_exp(exp):
    no_space = re.sub(' ', '', exp)
    r = re.compile('([+\-*/()]|\d+\.?\d*)')
    r_minus = re.compile('^[\d+\.?\d*]')
    # exp_fnl = r_minus.sub()
    exp_fnl = r.findall(no_space)
    exp_li = list(exp_fnl)
    if exp_li[0] == '-':
        exp_li.insert(0, '0')
    for i in exp_li:
        idx = exp_li.index(i)
        if i == '(':
            # print(idx)
            if exp_li[idx + 1] == '-':
                exp_li.insert(idx + 1, '0')
                continue
    return exp_li


def Lukasiewicz(exp):
    li_1 = []  # li_1中的结果最后存的就是逆波兰表达式
    li_2 = []  # li_2中将用于暂时存放运算符并且在最终形成逆波兰表达式的时候,该栈是会清空的
    add_sub = ['+', '-']
    mul_dev = ['*', '/']

    li = fmt_exp(exp)
    for i in li:
        if i == ')':
            while True:
                if len(li_2):
                    tmp = li_2[-1]    # li_2的栈顶已经保存下来,在下一步进行pop,如果遇到'(', '('已经被弹出
                    li_2.pop()
                    if tmp != '(':
                        li_1.append(tmp)
                    else:
                        break
        elif i in add_sub:
            while len(li_2) and li_2[-1] in mul_dev:
                    li_1.append(li_2[-1])
                    li_2.pop()
            if len(li_2):
                if li_2[-1] != '(':
                    li_1.append(li_2.pop())
                    li_2.append(i)
                else:
                    li_2.append(i)
            else:
                li_2.append(i)
        elif i in mul_dev or i == '(':
            li_2.append(i)
        else:
            li_1.append(i)
    while len(li_2):
        li_1.append(li_2.pop())

    return li_1


def cal_Lukasiewicz(exp):
    li = []
    op = ['+', '-', '*', '/']
    for i in exp:
        if i in op:
            if len(li) > 2 or len(li) == 2:
                s2 = li.pop()
                s1 = li.pop()

                if i == '+':
                    tmp = float(s1) + float(s2)
                if i == '-':
                    tmp = float(s1) - float(s2)
                if i == '*':
                    tmp = float(s1) * float(s2)
                if i == '/':
                    tmp = float(s1) / float(s2)

                li.append(tmp)
        else:
            li.append(i)   # i.isdigit() 不能判断浮点数为数字
    print(li)


if __name__ == '__main__':
    # exp = '0-1-4*(3-10*(3*2-1*9/(3-4*5+ 4/2)))  +  10.5 - (4+7)'
    exp = '6-2*(-3)'
    # exp = '0-1-4*(3-10*(3*2-1*9/(3-4)))  +  10.5 - (4+7)'
    # exp = '1 + 2 * 3 - (4 * 5 + 6) * 7'
    # 123*+45*6+7*+
    # exp = '(5 * (((9 + 8) * (4*6))+7))'
    # 598+46**7+*

    print(exp)
    ret = Lukasiewicz(exp)
    print(ret)
    t = cal_Lukasiewicz(ret)

你可能感兴趣的:(Python计算器之逆波兰实现)