conversion from infix to prefix

后端 未结 14 1278
有刺的猬
有刺的猬 2020-12-09 10:24

I am preparing for an exam where i couldn\'t understand the convertion of infix notation to polish notation for the below expression:

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


        
相关标签:
14条回答
  • 2020-12-09 10:56

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

    The shunting yard algorithm can also be applied to produce prefix notation (also known as polish notation). To do this one would simply start from the end of a string of tokens to be parsed and work backwards, reverse the output queue (therefore making the output queue an output stack), and flip the left and right parenthesis behavior (remembering that the now-left parenthesis behavior should pop until it finds a now-right parenthesis).

    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 through:

    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 ]
    
    0 讨论(0)
  • 2020-12-09 10:58

    here is an java implementation for convert infix to prefix and evaluate prefix expression (based on rajdip's algorithm)

    import java.util.*;
    
    public class Expression {
        private static int isp(char token){
            switch (token){
                case '*':
                case '/':
                    return 2;
                case '+':
                case '-':
                    return 1;
                default:
                    return -1;
            }
        }
        private static double calculate(double oprnd1,double oprnd2,char oprt){
            switch (oprt){
                case '+':
                    return oprnd1+oprnd2;
                case '*':
                    return oprnd1*oprnd2;
                case '/':
                    return oprnd1/oprnd2;
                case '-':
                    return oprnd1-oprnd2;
                default:
                    return 0;
            }
        }
        public static String infix2prefix(String infix) {
            Stack<String> OperandStack = new Stack<>();
            Stack<Character> OperatorStack = new Stack<>();
            for(char token:infix.toCharArray()){
                if ('a' <= token && token <= 'z')
                    OperandStack.push(String.valueOf(token));
                else if (token == '(' || OperatorStack.isEmpty() || isp(token) > isp(OperatorStack.peek()))
                    OperatorStack.push(token);
                else if(token == ')'){
                    while (OperatorStack.peek() != '(') {
                        Character operator = OperatorStack.pop();
                        String RightOperand = OperandStack.pop();
                        String LeftOperand = OperandStack.pop();
                        String operand = operator + LeftOperand + RightOperand;
                        OperandStack.push(operand);
                    }
                    OperatorStack.pop();
                }
                else if(isp(token) <= isp(OperatorStack.peek())){
                    while (!OperatorStack.isEmpty() && isp(token)<= isp(OperatorStack.peek())) {
                        Character operator = OperatorStack.pop();
                        String RightOperand = OperandStack.pop();
                        String LeftOperand = OperandStack.pop();
                        String operand = operator + LeftOperand + RightOperand;
                        OperandStack.push(operand);
                    }
                    OperatorStack.push(token);
                }
            }
            while (!OperatorStack.isEmpty()){
                Character operator = OperatorStack.pop();
                String RightOperand = OperandStack.pop();
                String LeftOperand = OperandStack.pop();
                String operand = operator + LeftOperand + RightOperand;
                OperandStack.push(operand);
            }
            return OperandStack.pop();
        }
        public static double evaluatePrefix(String prefix, Map values){
            Stack<Double> stack = new Stack<>();
            prefix = new StringBuffer(prefix).reverse().toString();
            for (char token:prefix.toCharArray()){
                if ('a'<=token && token <= 'z')
                    stack.push((double) values.get(token));
                else {
                    double oprnd1 = stack.pop();
                    double oprnd2 = stack.pop();
                    stack.push(calculate(oprnd1,oprnd2,token));
                }
            }
            return stack.pop();
        }
        public static void main(String[] args) {
            Map dictionary = new HashMap<>();
            dictionary.put('a',2.);
            dictionary.put('b',3.);
            dictionary.put('c',2.);
            dictionary.put('d',5.);
            dictionary.put('e',16.);
            dictionary.put('f',4.);
            dictionary.put('g',7.);
            String s = "((a+b)/(c-d)+e)*f-g";
            System.out.println(evaluatePrefix(infix2prefix(s),dictionary));
        }
    }
    
    0 讨论(0)
提交回复
热议问题