在Infthon中将中缀转换为前缀

时间:2016-03-02 22:14:51

标签: python

我正在尝试编写一个Infix到前缀转换器,例如我想转换一下:

1 + ((C + A ) * (B - F))

类似于:

add(1, multiply(add(C, A), subtract(B, F)))

但我得到了这个:

multiply(add(1, add(C, A), subtract(B, F)))

这是我到目前为止的代码

postfix = []
temp = []
newTemp = []

def textOperator(s):
    if s is '+':
        return 'add('
    elif s is '-':
        return 'subtract('
    elif s is '*':
        return 'multiply('
    else:
        return ""

def typeof(s):
    if s is '(':
        return leftparentheses
    elif s is ')':
        return rightparentheses
    elif s is '+' or s is '-' or s is '*' or s is '%' or s is '/':
        return operator
    elif s is ' ':
        return empty    
    else :
        return operand                          

infix = "1 + ((C + A ) * (B - F))"

for i in infix :
    type = typeof(i)
    if type is operand:
        newTemp.append(i)
    elif type is operator:
        postfix.append(textOperator(i))
        postfix.append(newTemp.pop())
        postfix.append(', ')
    elif type is leftparentheses :
        newTemp.append(i)
    elif type is rightparentheses :
        next = newTemp.pop()
        while next is not '(':
            postfix.append(next)
            next = newTemp.pop()
            postfix.append(')')
            newTemp.append(''.join(postfix))
            while len(postfix) > 0 :
                postfix.pop()
    elif type is empty:
        continue
    print("newTemp = ", newTemp)
    print("postfix = ", postfix)

while len(newTemp) > 0 :
    postfix.append(newTemp.pop())
postfix.append(')')

print(''.join(postfix)) 

有人可以帮我弄清楚如何解决这个问题。

1 个答案:

答案 0 :(得分:2)

我看到,使用括号子句,是一个递归问题,迫切需要一个递归解决方案。以下是对您的程序的重新思考,可能会给您一些关于如何重组它的想法,即使您没有购买我的递归论证:

import sys
from enum import Enum

class Type(Enum):  # This could also be done with individual classes
    leftparentheses = 0
    rightparentheses = 1
    operator = 2
    empty = 3
    operand = 4

OPERATORS = {  # get your data out of your code...
    "+": "add",
    "-": "subtract",
    "*": "multiply",
    "%": "modulus",
    "/": "divide",
}

def textOperator(string):
    if string not in OPERATORS:
        sys.exit("Unknown operator: " + string)
    return OPERATORS[string]

def typeof(string):
    if string == '(':
        return Type.leftparentheses
    elif string == ')':
        return Type.rightparentheses
    elif string in OPERATORS:
        return Type.operator
    elif string == ' ':
        return Type.empty
    else:
        return Type.operand

def process(tokens):

    stack = []

    while tokens:
        token = tokens.pop()

        category = typeof(token)

        print("token = ", token, " (" + str(category) + ")")

        if category == Type.operand:
            stack.append(token)
        elif category == Type.operator:
            stack.append((textOperator(token), stack.pop(), process(tokens)))
        elif category == Type.leftparentheses:
            stack.append(process(tokens))
        elif category == Type.rightparentheses:
            return stack.pop()
        elif category == Type.empty:
            continue

        print("stack = ", stack)

    return stack.pop()

INFIX = "1 + ((C + A ) * (B - F))"

# pop/append work from right, so reverse, and require a real list
postfix = process(list(INFIX[::-1]))

print(postfix)

该程序的结果是如下结构:

('add', '1', ('multiply', ('add', 'C', 'A'), ('subtract', 'B', 'F')))

您应该能够将流程发布到您想要的字符串形式(再次,递归...)

PS:typenext是Python内置和/或保留字,不要将它们用于变量名称。

PPS:将INFIX[::-1]替换为sys.argv[1][::-1],您可以将测试用例传递给程序,看看它对它们的作用。

PPPS:就像你的原版一样,它只处理一位数字(或单字母变量),你需要提供一个比list()更好的标记器,以使其正常工作。