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:谢谢,这是后缀。后缀计算是迭代的——您将操作数推到堆栈上,然后处理运算符