逆波兰表达式 中缀表达式 后缀表达式

前言

逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示. [ 百度百科 ]

开始

1 .我们这里要实现的是 将中缀表达式转换成后缀表达式,然后再计算最终结果,参考博客。具体转化算法如下:

中缀表达式a+b*c+(d*e+f)*g,其转换成后缀表达式则为abc*+de*f+g*+。
转换过程需要用到栈,具体过程如下:
1)如果遇到操作数,我们就直接将其输出。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。

2.代码实现如下:


    /**
     * @param sign 运算符
     * @return int 运算符优先级
     */
    public static int getRank(Character sign) {
        switch (sign) {
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
                return 2;
        }
        return -1;
    }


    public static void main(String[] args) throws Exception {
        String expression = "a+b*c+(d*e+f)*g";
        Stack<Character> stackTemp = new Stack<Character>();
        Queue<Character> queueOut = new LinkedList<Character>();
        for (Character word : expression.toCharArray()) {
            if (word >= 'a' && word <= 'z') {
                queueOut.offer(word);
            } else if (word == '(') {
                stackTemp.push(word);
            } else if (word == ')') {
                char top = stackTemp.peek();
                while (!stackTemp.empty()) {
                    if (top == '(') {
                        stackTemp.pop();
                        break;
                    }
                    queueOut.offer(top);
                    stackTemp.pop();
                    top = stackTemp.peek();
                }
            } else {
                if (stackTemp.empty() || getRank(word) > getRank(stackTemp.peek())) {
                    stackTemp.push(word);
                } else {
                    while (!stackTemp.empty() && getRank(word) <= getRank(stackTemp.peek())) {
                        queueOut.offer(stackTemp.peek());
                        stackTemp.pop();
                    }
                    stackTemp.push(word);
                }
            }
        }

        while (!stackTemp.empty()) {
            queueOut.offer(stackTemp.peek());
            stackTemp.pop();
        }
        /*输出结果*/
        while (!queueOut.isEmpty()) {
            System.out.print(queueOut.poll());
        }
    }

3.输出结果即后缀表达式(逆波兰表达式):abc*+de*f+g*+
4.计算逆波兰表达式,得到最终运算结果,待续.

结束

原文地址:https://www.cnblogs.com/alvis/p/9438832.html