题解 | #四则运算#

四则运算

https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e

d = input().strip()

expression = []

oprs = [] # 存储运算符栈
nums = [] # 存储运算数栈

ops = {
    "*": lambda x, y: x * y,
    "/": lambda x, y: x / y,
    "-": lambda x, y: x - y,
    "+": lambda x, y: x + y,
}


def recursive(expression: list[str], start: int):
    i = start
    oprs = []
    nums = []
    while i < len(expression):
        cur = expression[i]
        if cur.isnumeric():
            nums.append(int(cur))
            i += 1
        elif cur in "+":
            # 加法优先级最低,直接入 oprs 栈
            oprs.append(cur)
            i += 1
        elif cur == "-":
            # 如果是减号,需要考虑减号后是否是数字,以及判断在此次调用中是否在表达式的开头
            if nums:
                # nums 栈非空,则不是在表达式开头,先入一个 + 号到 oprs 栈
                # 因为减一个数等于加一个负数
                oprs.append("+")
            if expression[i + 1].isnumeric():
                # 如果减号后跟的是一个数字,则减号和这个数字一起入 nums 栈,表示一个负数
                nums.append(int(cur + expression[i + 1]))
                # 指针需向后移两位
                i += 2
            else:
                # 如果减号后不是数字,那么只能是括号,进行递归调用,优先计算括号内的
                r, step = recursive(expression, i + 2)
                i = step
                # 将括号内计算的值连同减号一起入 nums 栈
                nums.append(-r)
        elif cur in "([{":
            # 左括号,递归调用优先计算括号内的
            r, step = recursive(expression, i + 1)
            nums.append(r)
            i = step
            # 计算完括号内的,需查看当前左括号前的运算符是不是  */ 中的一种
            if oprs and oprs[-1] in '*/':
                # 是 */ 中的一种,则优先计算
                o = oprs.pop()
                num1 = nums.pop()
                num2 = nums.pop()
                r = ops[o](num2, num1)
                nums.append(r)
        elif cur in ")]}":
            # 遇到右括号,将 oprs 栈内的运算符一个一个的出栈
            # 每出一个运算符,同时出栈两个运算数来进行计算
            # 并且注意由于栈的先入后出的特点,后出栈的运算数,是在运算中的第一个运算数
            while oprs:
                o = oprs.pop()
                num1 = nums.pop()
                num2 = nums.pop()
                r = ops[o](num2, num1)
                nums.append(r)
            return nums[0], i + 1
        elif cur in "*/":
            # 如果遇到 */,由于 */ 的优先级更高,先判断 */ 后是否是数字
            nxt = expression[i + 1]
            i += 1
            # 如果是数字则优先计算
            if nxt.isnumeric():
                num = nums.pop()
                r = ops[cur](num, int(nxt))
                nums.append(r)
                i += 1
            else:
                oprs.append(cur)
    # 当循环结束时,有可能 oprs 中存在优先级低的运算符
    # 需要将 oprs 中的运算符全部取出做计算
    while oprs:
        o = oprs.pop()
        num1 = nums.pop()
        num2 = nums.pop()
        r = ops[o](num2, num1)
        nums.append(r)

    return nums[0], len(expression) - 1


i = 0

while i < len(d):
    if d[i].isnumeric():
        temp = d[i]
        is_break = False
        for j in range(i + 1, len(d)):
            if d[j].isnumeric():
                temp += d[j]
            else:
                expression.append(temp)
                is_break = True
                i = j
                break
        if not is_break:
            i += 1
            expression.append(temp)
    else:
        expression.append(d[i])
        i += 1

r, _ = recursive(expression, 0)
print(r)

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务