起源
《算法4th》中介绍了Java实现的“Dijkstra的双栈算数表达式求值法”, 让人想到python中的eval函数, 何不自己实现试试呢?
双栈算数表达式求值法
输入为(算子 算符 算子), 必须有括号, 简化思考和代码.
材料: 俩栈, 分别为a算子栈, b算符栈
a: 存储算子(数字)
b: 存储算符
忽略所有右括号(, 将输入字符串视为队列, 将字符依次出队, 遇到算子, 入a队, 遇到非(或)算符, 入b队. 遇到), 将a出栈俩元素(俩算子), b出栈一个元素(一个算符), 进行运算后结果压入a(参加下一轮运算). 当字符串为空时, 运算完毕, a中仅剩唯一一个算子, 即为最终结果.
具体参考《算法4th》 P80.
class Evaluate(object):
def __init__(self, formula):
self.ops = [] # 算子栈
self.vals = [] # 算符栈
if formula.strip() != "":
for s in formula: # 在不支持字符串字符迭代的语言中, 应用队列实现
if s == "(":
pass
elif s == "+":
self.ops.append(s)
elif s == "-":
self.ops.append(s)
elif s == "*":
self.ops.append(s)
elif s == "/":
self.ops.append(s)
elif s == ")": # 计算括号内表达式
op = self.ops.pop()
v = self.vals.pop()
if op == "+":
v += self.vals.pop()
elif op == "-":
v = self.vals.pop() - v
elif op == "*":
v *= self.vals.pop()
elif op == "/":
v = self.vals.pop() / v
self.vals.append(v)
else: # 非算符, 即算子, 则压入算子栈
self.vals.append(float(s))
print(self.vals.pop())
evaluate = Evaluate("((3*4)+1)")
Output:
13