中缀表达式转后缀表达式--Java

来源:互联网 发布:守望先锋左上角6个数据 编辑:程序博客网 时间:2024/05/29 11:24

利用自己用数组实现的ArrayStack(与常规的栈功能基本一致)实现将中缀表达式变成后缀表达式。这个题目应该都有见过,自己也是看了些资料,加上自己的理解实现的,这里记录一下,给自己以后看。如果觉得可以,也分享一下。

例如:

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

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

思路:

1)读到一个操作符时,把它放到栈中,在栈里面的操作符表示被挂起。
2)再读到一个操作符时,若当前操作符比栈顶的操作符优先级别低,或者同优先级,栈中操作符弹出; 当前操作符优先级高,则入栈;
3)在栈外面的左括号 ( 优先级最高,从而在栈中挂起的操作符还是挂起的,将 ( 入栈,

       而当 (入栈后,把它看做优先级最低的,再读到操作符 都按照上面的规则入栈或出栈;

4)读到右括号 )时,将栈中运算符都弹出,直到遇到栈中的左括号(,左括号也弹出;

=================================================

下面先给出自己一开始的代码实现:

public String infixToPostfix2(String str) {
        MyStack<String> ms = new MyArrayStack<String>();
        ms.push("#"); // 避免空栈(空指针)

        String[] ss = str.trim().split(" ");
        StringBuilder sb = new StringBuilder();

        for (String s : ss) {
            if (s.matches("[0-9A-Za-z]")) { // 遇到数字,输出
                sb.append(s + " ");
            } else if (s.equals("(")) { // 读到左括号 ( 时
                ms.push(s);
            } else if (s.equals(")")) { // 遇到右括号
                while (!ms.top().equals("(")) { // 输出直至遇到左括号,左括号出栈但是不输出。
                    sb.append(ms.top() + " ");
                    ms.pop();
                }
                ms.pop(); //将左括号弹出
            } else if (s.equals("*") || s.equals("/")) { // 读到 * 或 / 时
                while (ms.top().equals("*") || ms.top().equals("/")) { // 栈顶运算符和读到的运算符 大于或同优先级,就输出
                        sb.append(ms.top() + " ");
                        ms.pop();
                    }
                ms.push(s); // 把 * 或  / 入栈
            } else if (s.equals("+") || s.equals("-")) { // 读到 + 或 -
                while (!ms.top().equals("(") && !ms.top().equals("#")) { // 在栈中只有 左括号优先级最低
                        sb.append(ms.top() + " ");
                        ms.pop();
                    }
                ms.push(s);
                }
        }

        while (ms.top() != "#")
            sb.append(ms.pop() + " ");
        return sb.toString();
    }

------------------------------------------------

发现最后处理运算符时有代码重复,可以通过建立一个给运算符赋予优先级别的方法来 优化。参考自:http://blog.csdn.net/thehide/article/details/49928263

    public String infixToPostfix(String str) {
        MyStack<String> ms = new MyArrayStack<String>();
        ms.push("#"); // 避免空栈(空指针)

        String[] ss = str.trim().split(" ");
        StringBuilder sb = new StringBuilder();

        for (String s : ss) {
            String temp = ms.pop();
            if (s.matches("[0-9A-Za-z]")) { // 遇到数字,输出
                sb.append(s + " ");
                ms.push(temp);
            } else if (s.equals("(")) { // 读到左括号 ( 时
                ms.push(temp);
                ms.push(s);
            } else if (s.equals(")")) { // 遇到右括号
                while (!temp.equals("(")) { // 输出直至遇到左括号,左括号出栈但是不输出。
                    sb.append(temp + " ");
                    temp = ms.pop();
                }
            } else {
                while (getPriority(temp) >= getPriority(s)) { // 栈中运算符优先级大于或等于读到的运算符时,输出栈中运算符
                    sb.append(temp + " ");
                    temp = ms.pop();
                }

                ms.push(temp);
                ms.push(s);
            }
        }

        while (ms.top() != "#")
            sb.append(ms.pop() + " ");
        return sb.toString();
    }

    private int getPriority(String s) { // 定义 栈中 符号优先级
        if (s.equals("*") || s.equals("/"))
            return 2;
        if (s.equals("+") || s.equals("-"))
            return 1;
        if (s.equals("("))
            return 0;

        return -1;
    }



原创粉丝点击