0
点赞
收藏
分享

微信扫一扫

JAVA实现 中缀转后缀+逆波兰运算

狐沐说 2022-03-26 阅读 77
java算法

简易计算器


中缀变后缀

遍历字符串数组:

  1. 操作数直接输出。

  2. “*” “/” “(” -> 入栈。

  3. “)” -> 栈元素弹出直到遇到左括号。(左括号只弹出并不输出)

  4. “+” “-” -> 栈顶为操作数 则入栈;为运算符则 将其出栈。(可能多次出栈)

  5. 读完输入后,则将栈中剩余元素依次弹出。

peek() 前一定要 stack.isEmpty() == fasle !!!

// 返回类型根据需求更改
public static String[] mlConvert(String str) {
        Stack<String> op = new Stack<>();
         ArrayList<String> out = new ArrayList<>(); // 存后缀表达式

        String[] s = str.split("");
        StringBuilder result = new StringBuilder();

        for (String c : s) {
            switch (c) {
                case "*":
                case "/":
                case "(":
                    op.push(c); // 压制“弱小”
                    break;

                case "+":
                case "-":
                    while (!op.isEmpty()) {
                        if(op.peek().equals("+") || op.peek().equals("-") || op.peek().equals("*") || op.peek().equals("/"))
                        out.add(op.pop()); // 移出优先级高(等)的运算符
                        else break;
                    }

                    op.push(c); // 压入自己
                    break;


                case ")":


                    while (!op.isEmpty()) { // 匹配右括号
                        if(!op.peek().equals("("))
                        out.add(op.pop());
                        else break;
                    }

                    op.pop(); // "("
                    break;

                default: // 数字
                    out.add(c);
                    break;
            }


        }

        while (!op.isEmpty()){ // 剩余处理
            out.add(op.pop());
        }

        String[] o = new String[out.size()];

        for (int i = 0; i < out.size(); i++) {
            o[i] = out.get(i);
        }

        return  o;

        }

逆波兰运算

 public static int evalRPN(String[] tokens){ // 计算后缀表达式
        int returnValue = 0;
        String operators = "+-*/";

        Stack<String> stack = new Stack<>();

        for (String t : tokens) {
            if(!operators.contains(t)){
                stack.push(t); // 数字入栈
            }else {
                int a = Integer.parseInt(stack.pop());
                int b = Integer.parseInt(stack.pop());
                int index = operators.indexOf(t); // 觅符

                switch (index) { // 计算并将结果入栈
                    case 0 -> stack.push(String.valueOf(a + b));
                    case 1 -> stack.push(String.valueOf(a - b));
                    case 2 -> stack.push(String.valueOf(a * b));
                    case 3 -> stack.push(String.valueOf(a / b));
                }
            }
        }

        returnValue = Integer.parseInt(stack.pop()); // 结果出栈
        return returnValue;
    }

Dijkstra(双栈)

参考算法(第四版)

  1. 操作数入操作数栈

  2. 运算符入运算符栈

  3. 忽略左括号

  4. 遇到右括号,弹出一个运算符及所需操作数,将计算结果压入操作数栈

      public static void Dijkstra(String str){ //中缀表达式计算
            Stack<String> ops = new Stack<>();
            Stack<Double> vals = new Stack<>();
            String[] s1 = str.split("");
    
            for (String s : s1) {
                switch (s) { //
                    case "(":
                        break;
    
                    case "+":
                    case "-":
                    case "*":
                    case "/":
                    case "sqrt":
                        ops.push(s);
                        break;
    
                    case ")": { //
                        String op = ops.pop();
                        double v = vals.pop();
    
                        switch (op) {
                            case "+" -> v += vals.pop();
                            case "-" -> v -= vals.pop();
                            case "*" -> v *= vals.pop();
                            case "/" -> v /= vals.pop();
                            case "sqrt" -> v = Math.sqrt(v);
                        }
    
                        vals.push(v);
                        break;
                    }
    
                    default:
                        vals.push(Double.valueOf(s));
                        break;
                }
            }
    
            System.out.println(vals.pop());
        }
    
举报

相关推荐

0 条评论