您的位置:首页 > 编程语言 > Java开发

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

2017-08-17 17:15 246 查看
利用自己用数组实现的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;

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: