java实现中缀转后缀表达式

java实现中缀转后缀表达式

代码实现

public class Demo {
    public static void main(String[] args) {
        String expression = "1+((2+3)*4)-5";
        List<String> strings = toList(expression);
        List<String> suffixExression = toSuffixExression(strings);
        System.out.println(suffixExression);
    }

    public static List<String> toSuffixExression(List<String> list) {
        // 符号栈
        Stack<String> operas = new Stack<>();
        List<String> result = new ArrayList<>();

        // 遍历中缀表达式
        for (String s : list) {
            // 如果是一个数直接入result
            if (s.matches("\\d+")) {
                result.add(s);
            } else if ("(".equals(s)) {
                // 如果是一个(
                operas.push(s);
            } else if (")".equals(s)) {
                // 如果是一个),进行操作
                while (!"(".equals(operas.peek())) {
                    result.add(operas.pop());
                }
                // pop掉(
                operas.pop();
            } else {
                // 如果是操作符
                // s的优先级比栈顶小:将operas的运算符弹出并加入result,再次和operas新的运算符比较

                // 避免空栈,使用短路与
                while (operas.size() != 0 && priority(operas.peek()) >= priority(s)) {
                    // 将operas的栈顶加入result
                    result.add(operas.pop());
                }
                // 将当前的元素入operas
                operas.push(s);
            }
        }
        // 遍历结束后,将operas中所有元素加入result
        while (operas.size() != 0) {
            result.add(operas.pop());
        }
        return result;
    }

    public static List<String> toList(String s) {
        ArrayList<String> list = new ArrayList<>();
        // 用于多位数拼接
        StringBuilder str = new StringBuilder();
        // 每遍历到一个字符,便放入c中
        char c;

        for (int i = 0; i <= s.length() - 1; i++) {
            // 拿到每一个元素
            c = s.charAt(i);

            // 判断是不是数字
            if (c < 48 || c > 57) {
                // 如果是非数字
                list.add("" + c);
            } else {
                // 考虑多位数问题
                str.append(c);
                // 避免最后一位数有数组下标越界异常
                if ((i != s.length() - 1)) {
                    char next = s.charAt(i + 1);
                    if (next < 48 || next > 57) {
                        // 如果下一个是非数字
                        list.add(String.valueOf(str));
                        // 置空
                        str.delete(0, str.length());
                    }
                } else {
                    list.add(String.valueOf(str));
                }
            }
        }
        return list;
    }

    // 计算运算符的优先级
    public static int priority(String opera) {
        int priority = -1;
        // 预防栈顶元素为(
        if (opera.equals("(")) {
            return priority;
        }


        String[] operas = {"*", "/", "+", "-"};

        if (opera.equals(operas[0]) || opera.equals(operas[1])) {
            priority = 1;
        } else if (opera.equals(operas[2]) || opera.equals(operas[3])) {
            priority = 0;
        } else {
            throw new RuntimeException("运算符异常");
        }

        return priority;
    }

}
posted @ 2022-03-28 18:18  CoderCatIce  阅读(87)  评论(0编辑  收藏  举报