python练习(14)——使用栈实现eval函数的部分功能(加减乘除,括号运算, 负号)

# stack implement expression evaluation

priority = {'(': -1, ')': -1, '-': 0, '+': 0, '/': 1, '*': 1}
operator_map = {'+': lambda x, y: x + y, '-': lambda x, y: x - y, '/': lambda x, y: x / y, '*': lambda x, y: x * y}
operators = priority.keys()


def _exp(opr, opd, current_level, pop=False):
    """计算, 将前面优先级高的表达式先计算出来, 或将括号中的值计算出来,或最后运算所有的表达式

    current_level 为当前遍历运算符优先级, 前一个运算符优先级小与当前优先级, 表示所有计算已完成,则停止计算
    pop 表示是否将符号列表中的'('pop, 如果当前字符是')',则pop为True
    """

    while len(opd) >= 2:
        o = opr.pop()     # 运算子
        if o == '(':
            if not pop:
                opr.append(o)
            break
        if priority[o] < current_level:
            opr.append(o)
            break

        a = opd.pop()    # 运算数
        b = opd.pop()
        opd.append(operator_map[o](b, a))


def exp(s):
    opr = []             # 运算符集
    opd = []             # 运算子集
    levels = [-1]        # 记录当前优先级,每遇到一个括号,则增加一个优先级记录
    flag = False         # 正数累积,flag=False表示一个数字的开头
    for c in s:
        if c in operators:
            if c == '(':
                opr.append(c)
                levels.append(-1)
                continue
            if c == ')':
                _exp(opr, opd, -1, True)
                levels.pop()
                continue

            level = levels[-1]
            if level == -1 and c == '-':   # 开头-号, 填0, 增加level, 先算, 如果负号前有数字,则continue后,flag还是True,
                opr.append(c)
                opd.append(0)
                levels[-1] = float('inf')
                continue

            current_level = priority[c]

            if level >= current_level:
                _exp(opr, opd, current_level)
            levels[-1] = current_level
            opr.append(c)
            flag = False
        else:
            if flag:
                v = opd.pop() * 10 + int(c)
                opd.append(v)
                # print(opd, opr, levels)
                continue
            opd.append(int(c))
            flag = True

    if len(levels) != 1:      # 括号没封口
        raise TypeError('valid expression')

    _exp(opr, opd, -1)        # 最后计算

    if len(opr) != 0:         # 计算完,运算子集应为空
        raise TypeError('valid expression')

    return opd[-1]


if __name__ == '__main__':
    # s = input('>>>')
    # print(exp(s))
    ss = ['100-(-30+15)*5', '-1234-23+4*5-6', '-1*2/2-2+3']
    for s in ss:
        print(s, '=', exp(s), '........', eval(s))
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值