从中缀转换为前缀

时间:2009-12-22 14:59:44

标签: algorithm prefix notation

我正在准备考试,我无法理解中缀符号转换为上述表达式的波兰符号:

(a–b)/c*(d + e – f / g)

任何人都可以逐步告诉给定表达式如何转换为前缀?

13 个答案:

答案 0 :(得分:26)

Algorithm ConvertInfixtoPrefix

Purpose: Convert an infix expression into a prefix expression. Begin 
// Create operand and operator stacks as empty stacks. 
Create OperandStack
Create OperatorStack

// While input expression still remains, read and process the next token.

while( not an empty input expression ) read next token from the input expression

    // Test if token is an operand or operator 
    if ( token is an operand ) 
    // Push operand onto the operand stack. 
        OperandStack.Push (token)
    endif

    // If it is a left parentheses or operator of higher precedence than the last, or the stack is empty,
    else if ( token is '(' or OperatorStack.IsEmpty() or OperatorHierarchy(token) > OperatorHierarchy(OperatorStack.Top()) )
    // push it to the operator stack
        OperatorStack.Push ( token )
    endif

    else if( token is ')' ) 
    // Continue to pop operator and operand stacks, building 
    // prefix expressions until left parentheses is found. 
    // Each prefix expression is push back onto the operand 
    // stack as either a left or right operand for the next operator. 
        while( OperatorStack.Top() not equal '(' ) 
            OperatorStack.Pop(operator) 
            OperandStack.Pop(RightOperand) 
            OperandStack.Pop(LeftOperand) 
            operand = operator + LeftOperand + RightOperand 
            OperandStack.Push(operand) 
        endwhile

    // Pop the left parthenses from the operator stack. 
    OperatorStack.Pop(operator)
    endif

    else if( operator hierarchy of token is less than or equal to hierarchy of top of the operator stack )
    // Continue to pop operator and operand stack, building prefix 
    // expressions until the stack is empty or until an operator at 
    // the top of the operator stack has a lower hierarchy than that 
    // of the token. 
        while( !OperatorStack.IsEmpty() and OperatorHierarchy(token) lessThen Or Equal to OperatorHierarchy(OperatorStack.Top()) ) 
            OperatorStack.Pop(operator) 
            OperandStack.Pop(RightOperand) 
            OperandStack.Pop(LeftOperand) 
            operand = operator + LeftOperand + RightOperand 
            OperandStack.Push(operand)
        endwhile 
        // Push the lower precedence operator onto the stack 
        OperatorStack.Push(token)
    endif
endwhile 
// If the stack is not empty, continue to pop operator and operand stacks building 
// prefix expressions until the operator stack is empty. 
while( !OperatorStack.IsEmpty() ) OperatorStack.Pop(operator) 
    OperandStack.Pop(RightOperand) 
    OperandStack.Pop(LeftOperand) 
    operand = operator + LeftOperand + RightOperand

    OperandStack.Push(operand) 
endwhile

// Save the prefix expression at the top of the operand stack followed by popping // the operand stack.

print OperandStack.Top()

OperandStack.Pop()

End

答案 1 :(得分:5)

如果有什么关于什么中缀和前缀意味着你不太明白,我强烈建议你重读你教科书的那一部分。如果你对这个问题给出了正确的答案,你就不会给自己任何好处,但仍然不理解这个概念。

算法方面,它非常简单。你自己就像电脑一样。首先按照计算的顺序在每个计算周围放置一个parens。然后(再次按照从第一次计算到最后的顺序),只需在左侧的表达式前面移动操作符。之后,您可以通过删除parens来简化。

答案 2 :(得分:5)

(a–b)/c*(d + e – f / g)

前缀符号(反向抛光有操作符最后,不清楚你的意思,但原理将完全相同):

  1. (/ f g)
  2. (+ d e)
  3. (- (+ d e) (/ f g))
  4. (- a b)
  5. (/ (- a b) c)
  6. (* (/ (- a b) c) (- (+ d e) (/ f g)))

答案 3 :(得分:4)

(a–b)/c*(d + e – f / g)

第1步:(a-b)/c*(d+e- /fg))

第2步:(a-b)/c*(+de - /fg)

第3步:(a-b)/c * -+de/fg

第4步:-ab/c * -+de/fg

第5步:/-abc * -+de/fg

第6步:*/-abc-+de/fg

这是前缀表示法。

答案 4 :(得分:3)

我在youtube上看到了这个方法,因此在这里发布。

给定中缀表达式:(a-b)/ c *(d + e-f / g)

扭转它:

  

)G / F-E + d(* C /)B-A(

从左到右阅读字符 为操作员维护一个堆栈

 1. if character is operand add operand to the output
 2. else if character is operator or )
   2.1 while operator on top of the stack has lower or **equal** precedence than this character pop
   2.2 add the popped character to the output.
   push the character on stack

 3. else if character is parenthesis ( 
    3.1 [ same as 2 till you encounter ) . pop ) as well
 4. // no element left to read
   4.1 pop operators from stack till it is not empty
   4.2 add them to the output. 

reverse the output and print.

信用:youtube

答案 5 :(得分:1)

(a-b)/ c *(d + e - f / g)

请记住从最左边到最右边扫描表达式 从括号中开始 遵循WHICH COMES FIRST规则...... *,/,%处于同一水平且高于 +和-....所以 (a-b)= -bc前缀 (a-b)= bc-用于后缀 另一个带括号的术语: (d + e - f / g)=移动/首先 然后再加'+'先减去叹气' - '(记住它们在同一水平......) (d + e - f / g) 移动/第一 (d + e - (/ fg))=前缀 (d + e - (fg /))=后缀 然后是+然后 - ((+ de) - (/ fg))=前缀 ((de +) - (fg /))= postfix

( - (+ de)(/ fg))=前缀所以新表达式现在是 - + de / fg(1) ((de +)(fg /) - )=后缀所以新表达式现在是de + fg / - (2)

(a-b)/ c *因此

  1. (a-b)/ c *(d + e - f / g)= - bc前缀[-ab] / c * [ - + de / fg] --->取自(1)                                                / c *还没动 所以'/'在'*'之前首先出现,因为它们处于同一水平,移动'/' 到最右边:/ [ - ab] c * [ - + de / fg] 然后将'*'移到最右边

    • / [-ab] c [ - + de / fg] =删除分组符号= * / - abc- + de / fg - >前缀
  2. (a-b)/ c *(d + e - f / g)= bc-用于后缀[ab - ] / c * [de + fg / - ] --->取自(2) 所以'/'在''之前出现,因为它们处于同一水平,移动'/' 到最左边:[ab-] c [de + fg / - ] / 然后将''移到最左边 [ab-] c [de + fg / - ] / =删除分组符号= a b - c d e + f g / - / * - >后缀

答案 6 :(得分:0)

简单的谷歌搜索提出了this。毫无疑问,任何人都可以解释这一点。但我想在编辑之后,我可以尝试提出这些概念,以便您可以回答自己的问题。

提示:

学习考试,很难,你必须。预测你,成绩越高,我做:D

说明:

所有关于操作与操作数相关联的方式。每种表示法类型都有自己的规则。你只需要分解并记住这些规则。如果我告诉你我写了(2 * 2)/ 3作为[* /](2,2,3)你需要做的就是学习如何用前一种表示法转换后一种表示法。

我的自定义符号表示取前两个操作数并将它们复用,然后生成的操作数应除以第三个操作数。得到它 ?他们试图教你三件事。

  1. 对不同的符号感到满意。我给出的例子是汇编语言中的内容。操作数(你操作)和操作(你想对操作数做什么)。
  2. 计算中的优先规则不一定需要遵循数学中的规则。
  3. 评估:机器如何感知程序,以及它如何在运行时对它们进行排序。

答案 7 :(得分:0)

This algorithm will help you for better understanding .

Step 1. Push “)” onto STACK, and add “(“ to end of the A.

Step 2. Scan A from right to left and repeat step 3 to 6 for each element of A until the STACK is empty.

Step 3. If an operand is encountered add it to B.

Step 4. If a right parenthesis is encountered push it onto STACK.

Step 5. If an operator is encountered then: a. Repeatedly pop from STACK and add to B each operator (on the top of STACK) which has same or higher precedence than the operator. b. Add operator to STACK.

Step 6. If left parenthesis is encontered then a. Repeatedly pop from the STACK and add to B (each operator on top of stack until a left parenthesis is encounterd) b. Remove the left parenthesis.

Step 7. Exit

答案 8 :(得分:0)

https://en.wikipedia.org/wiki/Shunting-yard_algorithm

  

分流场算法也可用于产生前缀   符号(也称为波兰符号)。要做到这一点,就可以了   从要解析和工作的一串标记的末尾开始   向后,反转输出队列(因此​​产生输出队列   输出堆栈),并翻转左右括号行为   (记住现在左括号的行为应该弹出直到   它找到了一个现在正确的括号。)

from collections import deque
def convertToPN(expression):
    precedence = {}
    precedence["*"] = precedence["/"] = 3
    precedence["+"] = precedence["-"] = 2
    precedence[")"] = 1

    stack  = []
    result = deque([])
    for token in expression[::-1]:
        if token == ')':
            stack.append(token)
        elif token == '(':
            while stack:
                t = stack.pop()
                if t == ")": break
                result.appendleft(t)
        elif token not in precedence:
            result.appendleft(token)
        else:
            # XXX: associativity should be considered here
            # https://en.wikipedia.org/wiki/Operator_associativity
            while stack and precedence[stack[-1]] > precedence[token]:
                result.appendleft(stack.pop())
            stack.append(token)

    while stack:
        result.appendleft(stack.pop())

    return list(result)

expression = "(a - b) / c * (d + e - f / g)".replace(" ", "")
convertToPN(expression)

单步执行:

step 1 : token ) ; stack:[ ) ]
result:[  ]
step 2 : token g ; stack:[ ) ]
result:[ g ]
step 3 : token / ; stack:[ ) / ]
result:[ g ]
step 4 : token f ; stack:[ ) / ]
result:[ f g ]
step 5 : token - ; stack:[ ) - ]
result:[ / f g ]
step 6 : token e ; stack:[ ) - ]
result:[ e / f g ]
step 7 : token + ; stack:[ ) - + ]
result:[ e / f g ]
step 8 : token d ; stack:[ ) - + ]
result:[ d e / f g ]
step 9 : token ( ; stack:[  ]
result:[ - + d e / f g ]
step 10 : token * ; stack:[ * ]
result:[ - + d e / f g ]
step 11 : token c ; stack:[ * ]
result:[ c - + d e / f g ]
step 12 : token / ; stack:[ * / ]
result:[ c - + d e / f g ]
step 13 : token ) ; stack:[ * / ) ]
result:[ c - + d e / f g ]
step 14 : token b ; stack:[ * / ) ]
result:[ b c - + d e / f g ]
step 15 : token - ; stack:[ * / ) - ]
result:[ b c - + d e / f g ]
step 16 : token a ; stack:[ * / ) - ]
result:[ a b c - + d e / f g ]
step 17 : token ( ; stack:[ * / ]
result:[ - a b c - + d e / f g ]

# the final while
step 18 : token ( ; stack:[  ]
result:[ * / - a b c - + d e / f g ]

答案 9 :(得分:0)

在前缀表达式中,运算符首先出现操作数:+ ab [oprator ab]

中缀: (a–b)/c*(d + e – f / g)

第1步:(a - b) = (- ab) ['('具有最高优先级)

第2步:(d + e - f / g) = (d + e - / fg) [' /'优先级最高]

                       = (+ de - / fg )

          ['+','-' has same priority but left to right associativity]

                       = (- + de / fg)

第3步:(-ab )/ c * (- + de / fg) = / - abc * (- + de / fg)

                                 = * / - abc - + de / fg 

前缀: * / - abc - + de / fg

答案 10 :(得分:0)

使用Stack中缀到PostFix:

     Example: Infix-->         P-Q*R^S/T+U *V
     Postfix -->      PQRS^*T/-UV

     Rules:
    Operand ---> Add it to postfix
    "(" ---> Push it on the stack
    ")" ---> Pop and add to postfix all operators till 1st left parenthesis
   Operator ---> Pop and add to postfix those operators that have preceded 
          greater than or equal to the precedence of scanned operator.
          Push the scanned symbol operator on the stack

答案 11 :(得分:-1)

也许你在谈论Reverse Polish Notation?如果是,您可以在维基百科上找到转换的非常详细的分步示例;如果不是,我不知道你在问什么:(

您可能还想阅读我提供此类实施的另一个问题的答案:C++ simple operations (+,-,/,*) evaluation class

答案 12 :(得分:-2)

这是使用堆栈的算法。
只需遵循以下简单步骤即可。

1.反转给定的中缀表达式。

2.更换'(' with')'和')'用'('在反向表达式中。

3.现在将标准中缀应用于后缀子程序。

4.反转已建立的后缀表达式,这将给出必需的前缀表达式。

如果您发现步骤3困难,请咨询http://scanftree.com/Data_Structure/infix-to-prefix 其中还给出了一个成功的例子。