ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

6, java数据结构和算法: 栈的应用, 逆波兰计算器, 中缀表达式--> 后缀表达式

2020-06-02 23:01:27  阅读:220  来源: 互联网

标签:java 中缀 pop else 运算符 str cal 表达式


直接上代码:

public class PolandCalculator {
    //栈的应用:波兰计算器:  即: 输入一个字符串,来计算结果, 比如 1+((2+3)×4)-5 结果为16
    public static void main(String[] args) throws Exception {
        /**
         *  思路:
         *  1: 将 1+((2+3)×4)-5 (这叫中缀表达式,运算符再数字中间), 转换为后缀表达式 (1 2 3 + 4 × + 5 –)
         *  2: 使用栈, 将后缀表达式 , 计算得出结果
         *
         *  因为 后缀表达式, 来计算会变得简单易懂, 不需要那么多的判断, 只需要 数入栈,然后判断运算符, 从栈中pop出二个数,计算,并把结果入栈, 循环往复,得到最终结果
         */

        String str = "1+((2+3)*4)-5";
        // 1, 先将 str 字符串变为对应的 中缀表达式 midExpressionList(便于显示)
        List<String> midExpressionList = toMidExpressionList(str);
        System.out.println("前缀表达式为: "+midExpressionList);
        // 2, 将 midExpressionList 转换为 后缀表达式对应的 suffixExpressionList
        List<String> suffixExpressionList = toSuffixExpressionList(midExpressionList);
        System.out.println("后缀表达式为: "+suffixExpressionList);
        // 3, 计算结果
        calculator(suffixExpressionList);
    }

    private static List<String> toMidExpressionList(String s) {
        //定义一个List,存放中缀表达式 对应的内容
        List<String> ls = new ArrayList<String>();
        int i = 0; //这时是一个指针,用于遍历 中缀表达式字符串
        String str; // 对多位数的拼接
        char c; // 每遍历到一个字符,就放入到c
        do {
            //如果c是一个非数字,我需要加入到ls
            if((c=s.charAt(i)) < 48 ||  (c=s.charAt(i)) > 57) {
                ls.add("" + c);
                i++; //i需要后移
            } else { //如果是一个数,需要考虑多位数
                str = ""; //先将str 置成"" '0'[48]->'9'[57]
                while(i < s.length() && (c=s.charAt(i)) >= 48 && (c=s.charAt(i)) <= 57) {
                    str += c;//拼接
                    i++;
                }
                ls.add(str);
            }
        }while(i < s.length());
        return ls;//返回
    }

    private static List<String> toSuffixExpressionList(List<String> midExpressionList) {
        //1, 定义一个栈 用来存运算符
        Stack<String> cal = new Stack<String>();
        //2, 定义一个list 来做存中间结果和返回,  也可以定义一个栈, 但是用栈的话, 这个转换过程并没有pop操作, 而且还要逆序显示,比较麻烦, 所以用list
        List<String> resList = new ArrayList<String>();
        for (String str : midExpressionList) {
            if(str.matches("\\d+")){
                //是一个或多个数字, 就存入resList
                resList.add(str);
            }else if (str.equals("(")){
                //如果是 左括号 , 就加入cal  栈
                cal.push(str);
            }else if(str.equals(")")){
                //如果是右括号,  此时需要将cal 栈的运算符号,依次pop,并加入到resList中, 直到遇到"左括号"停止,  最后将"左括号"删除
                while(! cal.peek().equals("(")){
                    resList.add(cal.pop());
                }
                cal.pop();//跳出循环时,已经将"("之前的运算符都存入resList中,  此一步是将"("删除
            }else {
                //是运算符 +,-,*,/  , 如果是运算符, 如果cal栈为空,直接加入栈,  如果该运算符 优先级小于等于 cal栈顶运算符, 将cal栈中运算符 依次pop,加入到resList中, 知道运算符优先级大于为止
                while(cal.size() != 0 && operator(str) <= operator(cal.peek())){
                    resList.add(cal.pop());
                }
                cal.push(str);
            }
        }
        //最后将 cal栈中的运算符依次弹出加入到resList中
        while(cal.size() != 0){
            resList.add(cal.pop());
        }
        return resList;
    }

    private static int operator(String str) {
        if(str.equals("+") || str.equals("-")){
            return 1;
        }
        if(str.equals("*") || str.equals("/")){
            return 2;
        }
        return 0;
    }


    private static void calculator(List<String> suffixExpressionList) throws Exception {
        Stack<String> stack = new Stack<>();

        for (String str : suffixExpressionList) {
            if(str.matches("\\d+")){
                //是数字, 入栈
                stack.push(str);
            }else{
                //是运算符, 从栈中pop二个数, 计算,将计算结果存入stack中, 最终stack中的数, 就是计算结果
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;

                if(str.equals("+")){
                    res = num1 + num2;
                } else if(str.equals("-")){
                    res = num1 - num2;
                } else if(str.equals("*")){
                    res = num1 * num2;
                } else if(str.equals("/")){
                    res = num1 / num2;
                } else{
                    throw new Exception("没有这个运算符:"+str);
                }
                //计算结果  入栈
                stack.push(String.valueOf(res));
            }
        }
        System.out.println("最终的计算结果为:" + stack.pop());
    }

}

测试结果:

在测试一个:

标签:java,中缀,pop,else,运算符,str,cal,表达式
来源: https://www.cnblogs.com/lvcai/p/13034463.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有