问题描述
小F面临一个编程挑战:实现一个基本的计算器来计算简单的字符串表达式的值。该字符串表达式有效,并可能包含数字(0-9)、运算符+、-及括号()。注意,字符串中不包含空格。除法运算应只保留整数结果。请实现一个解析器计算这些表达式的值,且不使用任何内置的eval函数。
测试样例
样例1:
输入:
expression = "1+1"
输出:2
样例2:
输入:
expression = "3+4*5/(3+2)"
输出:7
思路
1. 理解问题
我们需要解析一个包含数字、运算符(+、-、*、/)和括号的字符串表达式,并计算其值。表达式中的数字是单个数字(0-9),运算符的优先级为:* 和 / 高于 + 和 -,括号可以改变运算的优先级。
可以使用栈(Stack)数据结构来处理运算符和操作数的优先级。
2. 数据结构选择
- 数字栈(num) :用于存放操作数(数字)。
- 运算符栈(op) :用于存放运算符。
3. 算法步骤
-
初始化:创建两个栈,一个用于存放数字,一个用于存放运算符。
-
遍历表达式:逐个字符处理表达式。
-
数字:直接压入数字栈。
-
左括号
(:直接压入运算符栈。 -
右括号
):弹出运算符栈中的运算符,直到遇到左括号(,并执行相应的运算。 -
运算符:
- 如果当前运算符的优先级低于或等于栈顶运算符的优先级,则弹出栈顶运算符并执行运算,直到满足条件为止。
- 将当前运算符压入运算符栈。
-
-
处理剩余运算符:遍历完表达式后,如果运算符栈中还有运算符,则依次弹出并执行运算。
-
返回结果:最终数字栈中的唯一元素即为表达式的计算结果。
细节
优化运算符处理
在处理运算符时,可以优化判断条件,确保只有在必要时才进行运算
处理除法时的整数结果
确保除法运算结果为整数,可以使用整除运算符 //。
def solution(expression):
num = [] # 用来存放数字的栈
op = [] # 用来存放运算符的栈
pr = {'+': 1, '-': 1, '*': 2, '/': 2} # 运算符优先级
def eval():
a = num.pop()
b = num.pop()
c = op.pop()
if c == '+':
x = b + a
elif c == '-':
x = b - a
elif c == '*':
x = a * b
else: # c == '/'
x = b // a # 用整除,确保结果为整数
num.append(x)
i = 0
while i < len(expression):
t = expression[i]
if t.isdigit(): # 判断是否为数字
num.append(int(t)) # 将字符转换为数字
elif t == '(':
op.append(t)
elif t == ')':
while op and op[-1] != '(':
eval()
op.pop() # 弹出 '('
else: # 运算符
while op and op[-1] != '(' and pr[op[-1]] >= pr[t]:
eval()
op.append(t)
i += 1
while op: # 处理剩余的运算符
eval()
return num[-1] # 返回最终结果