Algorithm 计算器表达式计算器-前缀与后缀符号?
为以下表达式编写自己的计算器(表达式计算器):Algorithm 计算器表达式计算器-前缀与后缀符号?,algorithm,data-structures,Algorithm,Data Structures,为以下表达式编写自己的计算器(表达式计算器): 3+2*5 7+(8/2)*5 3*5+8*7 我的印象是,实现这一点的唯一合理方法是转换为前缀符号或后缀符号,然后从那里进行计算 我以前用后缀表示法做过这件事,看起来效果很好。当时我从某个地方(不记得现在在哪里)得到了一个想法,后缀符号对于这个姿势来说更为标准。我没有用前缀符号尝试过这个 为这项任务选择前缀符号和后缀符号的优缺点是什么?对于一个典型的面试问题(例如),什么是更好的选择?为什么 另外,Python的eval使用前缀、后缀还是完
3+2*5
7+(8/2)*5
3*5+8*7
我的印象是,实现这一点的唯一合理方法是转换为前缀符号或后缀符号,然后从那里进行计算
我以前用后缀表示法做过这件事,看起来效果很好。当时我从某个地方(不记得现在在哪里)得到了一个想法,后缀符号对于这个姿势来说更为标准。我没有用前缀符号尝试过这个
为这项任务选择前缀符号和后缀符号的优缺点是什么?对于一个典型的面试问题(例如),什么是更好的选择?为什么
另外,Python的
eval
使用前缀、后缀还是完全不同的方法?我的印象是,这是Python的eval
的源代码,但不太清楚一般策略是什么。没有必要先转换为前缀或后缀。如果您只想对它求值一次或几次,那么您可以在解析时进行求值。我通常使用如下递归下降:
import re
def evalExpr(infixStr):
# precedences for infix operators
precs = {'+':0 , '-':0, '/':1, '*':1, '^':2}
# functions of operators
funcs = {
'+': (lambda a,b: a+b),
'-': (lambda a,b: a-b),
'/': (lambda a,b: a/b),
'*': (lambda a,b: a*b),
'^': (lambda a,b: a**b)
}
# divide string into tokens
tokens = re.split(r' *([\(\)\+\-\*\^/]) *', infixStr)
tokens = [t for t in tokens if t!='']
# current parse position
pos = 0
# evaluate infix expression at the parse point,
# processing only operators above a given precedence
def eval2(minprec,closer=None):
nonlocal pos, tokens
# first we need a number or parenthesized expression
if (pos >= len(tokens)):
raise Exception("Unexpected end")
if (tokens[pos]=="("):
pos += 1
val = eval2(0,")")
pos += 1
else:
val = float(tokens[pos])
pos += 1
# gather operators that consume the value
while pos < len(tokens):
op = tokens[pos]
if op == closer:
return val
prec = precs.get(op)
if prec == None:
raise Exception("operator expected. got " + op)
if prec<minprec: # precedence too low for us
break
pos += 1 # operator OK
# get the argument on the operator's right
# this will go to the end, or stop at an operator
# with precedence <= prec
arg2 = eval2(prec+1,closer)
val = (funcs[op])(val, arg2)
if closer != None:
raise Exception("Expected " + closer)
return val
return eval2(0)
print(evalExpr("5+3*4^2+1")) # prints 54.0
print(evalExpr("7+(8/2)*5")) # prints 27.0
print(evalExpr("3*5+8*7")) # prints 71.0
重新导入
def evalExpr(infixStr):
#中缀运算符的先例
precs={'+':0'-':0'/':1'*':1'^':2}
#经营者的职能
funcs={
“+”:(λa,b:a+b),
“-”:(lambda,b:a-b),
“/”:(lambda a,b:a/b),
“*”:(λa,b:a*b),
“^”:(λa,b:a**b)
}
#将字符串划分为标记
tokens=re.split(r'*([\(\)\+\-\*\^/])*,infixStr)
令牌=[t表示令牌中的t,如果t!=']
#当前解析位置
pos=0
#在分析点计算中缀表达式,
#仅处理高于给定优先级的运算符
def eval2(minprec,closer=None):
非本地pos、令牌
#首先,我们需要一个数字或括号内的表达式
如果(pos>=len(令牌)):
引发异常(“意外结束”)
如果(令牌[pos]=“(”):
pos+=1
val=eval2(0,“)”)
pos+=1
其他:
val=浮动(代币[pos])
pos+=1
#收集使用该值的运算符
而pos 如果可以,您如何实现前缀评估?在执行操作之前,您需要参数@YvesDaoust您应该递归调用以计算参数,然后执行运算符。@MattTimmermans:谢谢,这是后缀。后缀计算是迭代的——您将操作数推到堆栈上,然后处理运算符