zoukankan      html  css  js  c++  java
  • 完整逆波兰计算器(Java)

    完整逆波兰计算器(Java)

    博客说明

    文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!

    功能

    支持 + - * / ( )
    多位数,支持小数,
    兼容处理, 过滤任何空白字符,包括空格、制表符、换页符

    基本思路

    中缀表达式转后缀表达式

    代码

    package stack;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Stack;
    import java.util.Collections;
    import java.util.regex.Pattern;
    
    public class ReversePolishMultiCalc {
        //匹配运算符
        static final String SYMBOL = "\+|-|\*|/|\(|\)";
    
        static final String LEFT = "(";
        static final String RIGHT = ")";
        static final String ADD = "+";
        static final String MINUS = "-";
        static final String TIMES = "*";
        static final String DIVISION = "/";
    
        //优先级
        static final int LEVEL_01 = 1;
        static final int LEVEL_02 = 2;
        static final int LEVEL_HIGH = Integer.MAX_VALUE;
    
        static Stack<String> stack = new Stack<>();
        static List<String> data = Collections.synchronizedList(new ArrayList<String>());
    
        //去除所有空白符号
        public static String replaceAllBlank(String s) {
            return s.replaceAll("\s+", "");
        }
    
        //判断是否为数字
        public static boolean isNumber(String s) {
            Pattern pattern = Pattern.compile("^[-\+]?[.\d]*$");
            return pattern.matcher(s).matches();
        }
    
        //判断是否是运算符
        public static boolean isSymbol(String s) {
            return s.matches(SYMBOL);
        }
    
        //匹配运算优先级
        public static int calcLevel(String s) {
            if ("+".equals(s) || "-".equals(s)) {
                return LEVEL_01;
            } else if ("*".equals(s) || "/".equals(s)) {
                return LEVEL_02;
            }
            return LEVEL_HIGH;
        }
    
        //匹配
        public static List<String> doMatch(String s) throws Exception {
            if (s == null || "".equals(s.trim())) throw new RuntimeException("data is empty");
            if (!isNumber(s.charAt(0) + "")) throw new RuntimeException("data illeagle,start not with a number");
            s = replaceAllBlank(s);
    
            String each;
            int start = 0;
    
            for (int i = 0; i < s.length(); i++) {
                if (isSymbol(s.charAt(i) + "")) {
                    each = s.charAt(i) + "";
                    if (stack.isEmpty() || LEFT.equals(each) || ((calcLevel(each) > calcLevel(stack.peek())) && calcLevel(each) < LEVEL_HIGH)) {
                        stack.push(each);
                    } else if (!stack.isEmpty() && calcLevel(each) <= calcLevel(stack.peek())) {
                        while (!stack.isEmpty() && calcLevel(each) <= calcLevel(stack.peek())) {
                            if (calcLevel(stack.peek()) == LEVEL_HIGH) {
                                break;
                            }
                            data.add(stack.pop());
                        }
                        stack.push(each);
                    } else if (RIGHT.equals(each)) {
                        while (!stack.isEmpty() && LEVEL_HIGH >= calcLevel(stack.peek())) {
                            if (LEVEL_HIGH == calcLevel(stack.peek())) {
                                stack.pop();
                                break;
                            }
                            data.add(stack.pop());
                        }
                    }
                    start = i;
                } else if (i == s.length() - 1 || isSymbol(s.charAt(i + 1) + "")) {
                    each = start == 0 ? s.substring(start, i + 1) : s.substring(start + 1, i + 1);
                    if (isNumber(each)) {
                        data.add(each);
                        continue;
                    }
                    throw new RuntimeException("data not match number");
                }
            }
            Collections.reverse(stack);
            data.addAll(new ArrayList<>(stack));
            System.out.println(data);
            return data;
        }
    
        //计算结果
        public static Double doCalc(List<String> list){
            Double d = 0d;
            if(list == null || list.isEmpty()){
                return null;
            }
            if(list.size() == 1){
                System.out.println(list);
                d = Double.valueOf(list.get(0));
                return d;
            }
            ArrayList<String> list1 = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                list1.add(list.get(i));
                if(isSymbol(list.get(i))){
                    Double d1 = doTheMath(list.get(i-2),list.get(i-1),list.get(i));
                    list1.remove(i);
                    list1.remove(i-1);
                    list1.set(i-2,d1+"");
                    list1.addAll(list.subList(i+1,list.size()));
                    break;
                }
            }
            doCalc(list1);
            return d;
        }
    
        //运算
        public static Double doTheMath(String s1,String s2,String symbol){
            Double result;
            switch (symbol){
                case ADD:
                    result = Double.valueOf(s1) + Double.valueOf(s2);
                    break;
                case MINUS:
                    result = Double.valueOf(s1) - Double.valueOf(s2);
                    break;
                case TIMES:
                    result = Double.valueOf(s1) * Double.valueOf(s2);
                    break;
                case DIVISION:
                    result = Double.valueOf(s1) / Double.valueOf(s2);
                    break;
                default:
                    result = null;
            }
            return result;
        }
    
        public static void main(String[] args) {
            String math = "12.8 + (2-3.55)*4+10/5.0";
            try{
                doCalc(doMatch(math));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
    }
    
    

    结果

    image-20200625174138211

    感谢

    尚硅谷

    万能的网络

    以及勤劳的自己
    关注公众号: 归子莫,获取更多的资料,还有更长的学习计划

  • 相关阅读:
    黄聪:WordPress动作钩子函数add_action()、do_action()源码解析
    黄聪:使用WORDPRESS自带AJAX方法
    黄聪:get_posts 函数 | wordpress
    黄聪:wordpress伪静态的原理
    黄聪:wordpress如何开启文章格式post format
    黄聪:Xmind修改默认字体风格设置
    黄聪:让WordPress主题支持语言本地化(使用poedit软件实现中文翻译功能)
    ArcGIS Pro二次开发-选择gdb
    arcgis pro2.5 改变地图范围
    创建用户SQL
  • 原文地址:https://www.cnblogs.com/guizimo/p/13192360.html
Copyright © 2011-2022 走看看