2014-02-20 2 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 и ==, is проверка возвращает значение ИСТИНА, если оба объекта так же == возвращает истину, если значение равны.

дополнительно Состояние:

s is '+' or '-': 

Должно быть:

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

Примечание нераскрытый пустая строка всегда верно, например,

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

Пока я согласен с вами и внесли изменения, это не меняет того факта, что оценка выражения не работает – JonStanley91

Смежные вопросы