逆波兰计算器的实现

学习完逆波兰表达式计算器的实现后,觉得有以下几点需要注意:

  1. 对拿到的字符串的分割处理,并将其放入ArrayList数组
  2. 将中缀表达式转换成后缀表达式的代码实现
  3. 使用了一个Java中自带的方法Integer.parseInt(),这个方法可以将字符串的"123",转换成int类型的123,减少了一些工作量

 下面是代码实现:

1、拿到一个由字符串组成的中缀表达式后,对该字符串的分割处理,并将其放入ArrayList数组中

    //将中缀表达式的由 字符串 转换成 ArrayList(动态数组)
    public static List toInfixExpressionList(String s) {

        List ls = new ArrayList();      //储存元素类型为 String的数组

        //辅助变量
        int item = 0;
        String str = "";
        char ch;

        do {

            //若不是数字,则直接加进 ls 数组中
            if ((ch = s.charAt(item)) < 48 || (ch = s.charAt(item)) > 57) {

                ls.add("" + ch);
                item++;

            } else {    //是数字,则需要判断多位数(小数功能的话,稍稍修改if的条件即可)

                str = "";
                while (item < s.length() && ((ch = s.charAt(item)) >= 48 && (ch = s.charAt(item)) <= 57)) {
                    str += ch;  //拼成一个长的字符串再放入
                    item++;
                }
                ls.add(str);
            }

        } while (item < s.length());

        return ls;
    }

实现效果如图:

2、将中缀表达式转换成后缀表达式:

    //将中缀表达式的 ArrayList 转换成 后缀表达式的 ArrayList
    public static List parseSuffixExpressionList(List ls) {

        //定义两个工具栈,一个存放运算符,一个存放转换结果
        Stack s1 = new Stack();     //符号栈

        List s2 = new ArrayList();  //储存中间结果的数组


        //遍历
        for (String item : ls) {

            //如果为数字,则压入s2
            if (item.matches("\\d+")) {       //正则表达式,判断是否是数字,是则压入数栈

                s2.add(item);

            } else if (item.equals("(")) {     //不是数字,是左括号,将左括号压入符号栈

                s1.push(item);

            } else if (item.equals(")")) {     //遇到右括号,则把符号栈“(”前的运算符压入 s2

                while (!s1.peek().equals("(")) {

                    s2.add(s1.pop());

                }

                s1.pop();      //丢弃左括号,注意:右括号从未入任何栈

            } else {

                //若当前 item 比 s1 栈顶元素优先级低,则将 s1 栈顶弹出,并加入到 s2 中
                while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {

                    s2.add(s1.pop());

                }

                s1.push(item);

            }

        }

        //将剩余的运算符加入到 s2 中
        while (s1.size() != 0) {

            s2.add(s1.pop());

        }


        return s2;
    }

效果如图,此时在转换过程中已经将小括号删去:

 

3、按计算方法,由后缀表达式计算结果输出:

(注意:此处使用了一个Java中自带的方法Integer.parseInt(),这个方法可以将字符串的"123",转换成int类型的123


    //完成逆波兰表达式的运算
    public static int calculate(List ls) {

        //Stack stack = new Stack();

        Stack stack = new Stack();

        for (String item :
                ls) {
            if (item.matches("\\d+")) {
                stack.push(item);
            } else {
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;
                if (item.equals("+")) {
                    res = num1 + num2;
                } else if (item.equals("-")) {
                    res = num1 - num2;
                } else if (item.equals("*")) {
                    res = num1 * num2;
                } else if (item.equals("/")) {
                    res = num1 / num2;
                } else {
                    throw new RuntimeException("运算符输入有误");
                }

                stack.push("" + res);

            }

        }


        return Integer.parseInt(stack.pop());


    }

效果如下: 

 

 

你可能感兴趣的:(Java)