简单四则运算解析器| 豆包MarsCode AI刷题

67 阅读3分钟

为了解决这个问题,可以使用栈结构来解析表达式,因为栈能够很好地处理嵌套的括号表达式。

解决思路

  1. 如何处理数字和运算符

• 表达式中包含数字和四则运算符,需要确定如何解析数字、识别操作符、以及如何进行相应的计算。

• 考虑将数字和运算符分开处理:我们可以用两个栈分别存储数字和运算符。

• 数字栈 nums 用于存储当前待计算的数字。

• 运算符栈 ops 用于存储待处理的操作符。

  1. 运算符优先级

• 不同运算符有不同的优先级:乘法和除法的优先级高于加法和减法,这会影响计算顺序。

• 可以定义一个 precedence 函数来确定每个运算符的优先级:

• + 和 - 的优先级为 1

• * 和 / 的优先级为 2

• 在处理表达式时,如果新遇到的运算符优先级低于栈顶运算符,则先计算栈顶的高优先级运算符。

  1. 括号处理

• 括号改变了优先级,所以我们需要特殊处理:

• 遇到 ( 时,将其直接压入 ops 栈,以表示一个新的优先级范围的开始。

• 遇到 ) 时,依次弹出并计算 ops 栈中的运算符,直到遇到 (,表示结束该优先级范围。

  1. 操作符的计算

• 当确定一个操作符需要计算时,例如遇到更低优先级或是 ),我们就可以使用一个 apply_operation 函数,来弹出并应用栈顶的运算符进行计算,将计算结果压回 nums 栈中。

  1. 解析表达式

• 逐字符解析表达式,根据字符的类型(数字、操作符或括号)执行相应的逻辑:

数字:累积成完整数字并压入 nums 栈。

运算符:根据优先级判断是否需要立即计算。

括号:处理新的优先级范围。

• 最后,将栈中剩余的所有运算符逐一计算完毕即可。

代码实现过程

  1. 初始化栈和变量: • 使用一个栈来存放每一个临时结果和符号。 • 设置变量 num 存储当前数字,sign 表示当前操作符(初始为 +)。 • 用变量 result 存储当前计算结果。
  2. 遍历字符串: • 遇到数字:将数字逐位累积到 num,确保能解析多位数。 • 遇到运算符 + -:将前面的 num 和符号处理到 result 中,并重置 num。更新 sign。 • 遇到 (:将当前 result 和 sign 压入栈中,并重置 result 和 sign。 • 遇到 ):先将当前 num 处理到 result 中,然后从栈中取出前一层的 sign 和 result 进行累加。
  3. 处理最后的数字:当遍历结束时,将剩余的 num 和 sign 处理到结果中。
  4. 整数除法:为保证运算结果只保留整数,对于负数除法,确保结果向零靠拢(可以通过 int(a / b) 实现)。

需要注意的是要考虑乘除法相较于加减法的优先级判断

def apply_operation(operators, values):
        right = values.pop()
        left = values.pop()
        op = operators.pop()
        
        if op == '+':
            values.append(left + right)
        elif op == '-':
            values.append(left - right)
        elif op == '*':
            values.append(left * right)
        elif op == '/':
            values.append(int(left / right))  # 确保整数除法

最终的执行过程

优先级处理:在栈中处理高优先级的操作符(乘法、除法)可以确保计算的正确顺序。

整数除法:确保每次除法运算结果都是整数。

多位数字支持:通过累积 num 支持多位数字解析。