中缀表达式转逆波兰表达式,逆波兰表达式的计算

中缀表达式转后缀表达式:

  1. 中缀表达式,是我们人可以识别的表达式形式;

  2. 后缀表达式是计算机可以识别的表达式形式。

大体思路:

  1. 将中缀表达式的每一个符号存放在ArrayList a里面
  2. 新建一个栈stack s来存储中间符号,创建一个ArrayList b存放后缀表达式(为什么不用栈呢?因为要将存入的字符遍历,先进先出,用List更加方便)
  3. 扫描a:
    • 如果是数字,直接放入b即可;
    • 如果是符号:
      • '(' : push到s中
      • ')' : push栈s中的栈顶元素,依次存入b中,直到遇到'(',且这对括号可以被丢弃了
      • 其他运算符:比较该运算符和s栈顶元素的优先级,若它的优先级高,则直接放入s中;若它的优先级<=栈顶元素的优先级,则将栈顶元素pop出来,存入b中,别忘了此时将该运算符继续与s栈顶元素比较
public static List<String> parseSuffixExpressionList(List<String> list) {
        //定义两个栈
        Stack<String> s1 = new Stack<>();   //符号栈
        //s2栈没有pop操作,需要逆序输出,如果用栈结构比较麻烦,所以可以用数组实现
        //Stack<String> s2 = new Stack<>();   //  存储结果
        ArrayList<String> s2 = new ArrayList<>();   //存储结果
        for (String ele : list) {
            //如果是一个数,则加入s2
            if (ele.matches("\\d+")) {
                s2.add(ele);
            } else if (ele.equals("(")) {
                s1.push(ele);
            } else if (ele.equals(")")) {
                //如果是右括号,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号未知,且这对括号呗丢弃
                while (!s1.peek().equals("(")) {
                    s2.add(s1.pop());
                }
                //左括号被弹出(消除括号)
                s1.pop();
            } else {
                //操作符的优先级
                //当ele的优先级小于等于s1栈顶运算符,将s1栈顶的运算符弹出并加入到s2,再次将ele与新的栈顶运算符比较
                while (s1.size() != 0 && Operation.getValue(ele) <= Operation.getValue(s1.peek())){
                    s2.add(s1.pop());
                }
                s1.push(ele);
            }
        }
        //将s1中的剩余的符号依次弹出并加入到s2;
        while (!s1.empty()){
            s2.add(s1.pop());
        }

        return s2;

    }
代码实现

 

那下面写如何计算逆波兰表达式吧

//完成对逆波兰表达式的运算
    public static int calculate(List<String> list) {
        //创建栈
        Stack<String> stack = new Stack<>();
        //遍历list
        for (String s : list) {
            if (s.matches("\\d+")) {
                //匹配是多位数
                stack.push(s);
            } else {
                //pop出两个数进行运算
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0; //存放结果
                if (s.equals("+")) {
                    res = num1 + num2;
                } else if (s.equals("-")) {
                    res = num1 - num2;
                } else if (s.equals("*")) {
                    res = num1 * num2;
                } else if (s.equals("/")) {
                    res = num1 / num2;
                } else {
                    throw new RuntimeException("运算符有误");
                }
                stack.push(res + "");
            }
        }
        //最后留在stack中的数据是结果
        return Integer.parseInt(stack.pop());
    }
代码实现

 

posted @ 2020-07-16 22:14  -忘情冷雨夜-  阅读(162)  评论(0)    收藏  举报