【题目】
给定一个字符串str,str表示一个公式,公式里可能有整数,加减乘除符号和左右括号,返回公式计算的结果。例如,str = 48×((70-65)-43)+8×1。返回-1816。
【说明】
可以认定给定的字符串一定是正确的公式,不需要对str做公式有效性检查。
如果是负数就需要有括号括起来,比如4*(-3)。但如果负数作为公式的开头或者括号部分的开头,则可以没有括号,比如-3*4和(-3*4)都是合法的。
- 不需要考虑溢出问题
【基本思路】
本题可以使用递归的方法。从左到右遍历str,如果遇到左括号就进入递归,相当于将括号里的内容当成一个新的公式,等括号里的内容计算完成后将结果返回,此时再接着继续遍历str,直到str遍历完或者遇到右括号,这样就相当于str中不再包含左右括号。递归过程需要返回两个结果,一个是当前子公式计算的结果,一个是当前遍历到的str的位置。这样上级递归函数就可以根据这两个数据继续向后遍历。计算公式的结果时,先将乘法和除法计算完,最后再统一计算计算加法和减法。
下面是使用python3.5实现的代码。
#公式字符串求值
def getValue(exp):
def value(exp, i):
deque = []
pre = 0
while i < len(exp) and exp[i] != ')':
if ord(exp[i]) >= ord('0') and ord(exp[i]) <= ord('9'):
pre = pre * 10 + int(exp[i])
i += 1
elif exp[i] != '(':
addNum(deque, pre)
deque.append(exp[i])
i += 1
pre = 0
else:
bra = value(exp, i + 1)
pre = bra[0]
i = bra[1] + 1
addNum(deque, pre)
return [getNum(deque), i]
#计算乘法除法
def addNum(deque, pre):
if deque:
top = deque.pop()
if top == '+' or top == '-':
deque.append(top)
else:
cur = int(deque.pop())
pre = cur * pre if top == '*' else cur / pre
deque.append(pre)
#计算加法减法
def getNum(deque):
res = 0
add = True
while deque:
cur = deque.pop(0)
if cur == '+':
add = True
elif cur == '-':
add = False
else:
res += int(cur) if add else -int(cur)
return res
return value(exp, 0)[0]