• 逆波兰表达式完整实现


      上篇中,我们只支持对整数实现,本篇完整实现,支持加减乘除和多位数、小数,思路与上篇相同。

    因此直接上代码实现过程

    package com.atxihua;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Stack;
    import java.util.regex.Pattern;
    
    public class reversePolishMultiCalc {
        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();
            }
        }
        /*
        * 匹配+ - * / ()运算符
        * */
        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 DIVISON="/";
    
        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 replaceAllBlack(String s){
      //\\s+匹配任何空白字符,包括空格、制表符、换页符等待,等价于[\f\n\r\t\v]
      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;
            }else {
                return LEVEL_HIGH;
            }
        }
    public static List<String> doMatch(String s){
            if(s==null||"".equals(s.trim()))throw new RuntimeException("data is empty");
            //进行简单校验,保证第一个是数字
            if(!isNumber(s.charAt(0)+""))throw new RuntimeException("data is illeagle,start not with a number");
            s=replaceAllBlack(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");
                }
            }
            //如果栈里还有元素,此时元素需要依次出栈入列,可以想象栈里剩下栈顶为/,栈底为+,应该依次出栈入列
            //可以直接反转整个stack添加到队列中
            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 DIVISON:result=Double.valueOf(s1)/Double.valueOf(s2);break;
            default:result=null;
        }
        return result;
        }
    }

    运行结果:

  • 相关阅读:
    "use strict"
    jquery.is()
    $.proxy
    windows检测文件夹是否更新.bat脚本 windows循环检查文件夹
    linux下串口多线程通信 ,多串口收发数据错乱问题解决办法
    linux串口配置详解
    linux socket 程序被ctrl+c或者异常终止,提示:bind error:Address already in use,解决办法
    linux下包含自定义.c文件 调用报错未定义解决办法
    linux下对一个文件写完马上读取,读到空白
    linux 下socket通信,client断开service退出解决办法
  • 原文地址:https://www.cnblogs.com/ftx3q/p/15725166.html
Copyright © 2020-2023  润新知