2014-02-20 29 views
0

我正在改变中缀到后缀,然后对其进行评估。创建后缀表达式时出错

#!/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 + 23 输出例如: 1 2 + 3 - = 0

如期望的工作原理,但是当我尝试这样的: 输入: 13 + 23 - 42 * 2

我得到 输出: 13 23 + 42 - 2 * = -12

代替: 13 23 + 42 2 * - = -48

我不确定发生了什么问题。有任何想法吗?

+0

并且不要使用'is'运算符来比较字符串,请使用'=='。 –

+0

还值得注意的是,你可以使用'dict'作为优先级和typeof ... –

+0

你是对的,我应该使用==,但是这并没有改变代码的功能。我仍然没有得到我想要的输出 – JonStanley91

回答

1

使用==代替is运营商,有is==之间的区别时,如果值相等的两个对象都是同一==返回true is检查返回True。

另外,条件:

s is '+' or '-': 

应该是:

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

注意一个非空字符串始终是真实的例如

>>> bool('') 
False 
>>> bool('+') 
True 
+0

尽管我同意你的观点并作出了修改,但这并没有改变评估表达式不起作用的事实 – JonStanley91