创建后缀表达式时出错

时间:2014-02-20 17:37:41

标签: python postfix-notation infix-notation

我正在将中缀更改为postfix,然后对其进行评估。

#!/usr/bin/python

import sys
import fileinput
import operator

operator_functions = {
    '+': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.div,
    '%': operator.mod
}

def tokenise( line ) :
    '''generator, serves up one token at a time
    input - a valid, openo file handle (object)
    output - next token (as a string)
    side-effects - input pointer is moved'''

    for tok in line.split() :
        yield tok

#Define types with corresponding ID numbers to distinguish them.
OPERATOR = 1
OPERAND = 2
LEFT_PARENTHESES = 3
RIGHT_PARENTHESES = 4

def precedence(s): #Returns the precedence of the operators
    if s == '(':
    return 3
elif s == '+' or s == '-':
    return 2
elif s == '*' or s == '/' or s == '%':
    return 1
else:
    return 0

def typeof(s): #Returns the type of the symbol
    if s == '(':
    return LEFT_PARENTHESES
elif s == ')':
    return RIGHT_PARENTHESES
elif s == '+' or s == '-' or s == '*' or s == '%' or s == '/':
    return OPERATOR  
else :
    return OPERAND                          

def infix2postfix(infix):
    postfix = []
    stack = []
    for i in infix:
        symbol_type = typeof(i)
        if symbol_type == LEFT_PARENTHESES :
            #If it is a left paren, push it onto the stack
            stack.append(i)
        elif symbol_type == RIGHT_PARENTHESES :
            #If it is a right paren, pop operators from the stack and append to the postfix expression,
            #until a left paren is encountered on the stack. Remove and discard the left paren                
            next = stack.pop()
            while next != '(':
                postfix.append(next)
                next = stack.pop()
        elif symbol_type == OPERAND:
            #If it is an operand, append it to the postfix expression
            postfix.append(i) 
        elif symbol_type == OPERATOR:
            #If it is an operator, then pop operators from the stack and append to the postfix expression
            #while the operators have equal or higher precedence than the current token. Push current
            #token (operator) onto the stack
            p = precedence(i)
            #print i
            while len(stack) != 0 and p <= precedence(stack[-1]) :
                print stack
                postfix.append(stack.pop())
            stack.append(i)

    while len(stack) > 0 : #Add to postfix
        postfix.append(stack.pop())
    evalPostfix(postfix) #Call evalPostFix to get result

def evalPostfix(postfix_expression):
    stack = []
    for token in postfix_expression :
        if token in operator_functions:
            no1 = int(stack.pop()) #First Number
            no2 = int(stack.pop()) #Second Number
            stack.append(operator_functions[token](no2, no1))
        else :
            stack.append(token)
    print ' '.join(postfix_expression),'=',stack.pop() #The Result

##########
#Main Code
##########
if len(sys.argv) == 2: #Read from file
    f = open( sys.argv[1] )
elif len(sys.argv) == 1: #Read from stdin
    f = sys.stdin
else:
    print 'Invalid Number of arguments. Supply either no arguments or an input file.'
    sys.exit(0)


lines = [line.strip() for line in f]

for i in lines:
    arr=[] #Array containing all infix expressions
    tokens = tokenise( i )
    for t in tokens :
        #print t
        arr.append(t)
    infix2postfix(arr) #Call infix2postfix

输入示例: 1 + 2 - 3 输出示例: 1 2 + 3 - = 0

这可以按照需要运行,但是当我尝试这个时: 输入: 13 + 23 - 42 * 2

我明白了 输出: 13 23 + 42 - 2 * = -12

而不是: 13 23 + 42 2 * - = -48

我不确定出了什么问题。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

使用==代替is运算符,is==之间存在差异,is当两个对象相同时,检查返回True {{1如果value相等则返回true。

另外,条件:

==

应该是:

s is '+' or '-':

注意非空字符串总是为真,例如

s == '+' or  s == '-':