zoukankan      html  css  js  c++  java
  • 结对开发

    本次结对开发主要是要开发一个可以用于四则运算调用的接口

    实现功能:JaxbUtil.java

    package com.core.util;
    
    import java.io.StringReader;
    import java.io.StringWriter;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    
    import com.core.bean.Option;
    
    public class JaxbUtil {
        
        //javabean转换成xml
        private static String converToXml(Object obj,String encoding) {
            String result = null;
            try {
                JAXBContext context = JAXBContext.newInstance(obj.getClass());
                Marshaller marshaller = context.createMarshaller();
                //是否格式化xml(按标签自动换行)
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                //设置编码方式
                marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
                StringWriter writer = new StringWriter();
                marshaller.marshal(obj, writer);
                result = writer.toString();
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
            return result;
        }
        
        public static String convertTomXml(Object object) {
            return converToXml(object, "UTF-8");
        }
        
        //xml转换成javabean
        @SuppressWarnings("unchecked")
        public static<T> T convertToJavaBean(String xml,Class<T> c) {
            T t = null;
            try {
                JAXBContext context = JAXBContext.newInstance(c);
                Unmarshaller unmarshaller = context.createUnmarshaller();
                t = (T)unmarshaller.unmarshal(new StringReader(xml));
            }catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
            
            return t;
        }
        
        public static void main(String[] args) {
            Option option = new Option();
            option.setOperation_num(4);
            option.setMin(-1000);
            option.setMax(1000);
            option.setPoint_long(2);
    //        System.out.println(convertTomXml(option));
            String xml = convertTomXml(option);
            
            Option option2=convertToJavaBean(xml, Option.class);
            System.out.println(option2.getMin()+"~"+option2.getMax());
        }
    }
    View Code

    计算功能:

    package com.core.bean;
    
    import java.math.BigDecimal;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Stack;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import com.core.util.JaxbUtil;
    
    public class Calculate {
        
        private static final Pattern EXPRESSION_PATTERN = Pattern.compile("[0-9\.+-/*()= ]+");
    
        private static final Map<String,Integer> OP_PRIORITY_MAP = new HashMap<String ,Integer>() {
            /**
             * 
             */
            private static final long serialVersionUID = -5028404412583819744L;
    
            {
                put("(",0);
                put("+",2);
                put("-",2);
                put("*",3);
                put("/",3);
                put(")",7);
                put("=",20);
            }
        };
        
        //不带xml参数的计算
        public static String Calc(String expression) throws MyException {
            
            //判断表达式是否为空
            if(expression==null||expression.equals("")) {
                throw new IllegalArgumentException("表达式不能为空!");
            }
            
            Matcher matcher = EXPRESSION_PATTERN.matcher(expression);
            if(!matcher.matches()){
                throw new IllegalArgumentException("表达式含有非法字符!");
            }
            
            expression = formatExpression(expression);
            isExpression(expression);
            
            Stack<String> optstack = new Stack<>();
            Stack<BigDecimal> numStack = new Stack<>();
            StringBuilder numBuilder = new StringBuilder(16);
            char pre;
            
            
            
            for(int i=0;i<expression.length();i++) {
                char ch = expression.charAt(i);
                
                if(ch!=' ') {
                    pre = ch;
                    
                    if((ch>='0'&&ch<='9')||ch=='.') {
                        numBuilder.append(ch);
                    }else {
                        if(numBuilder.length()>0) {
                            if(isNum(numBuilder.toString())==false) {
                                throw new MyException("表达式格式错误!————数字格式错误(错误数字:'"+numBuilder+"'");
                            }
                            numStack.push(new BigDecimal(numBuilder.toString()));
                            numBuilder.delete(0, numBuilder.length());
                        }
                        String operation = String.valueOf(ch);
                        if(optstack.empty()) {
                            optstack.push(operation);
                        }else {
                            if(operation.equals("(")) {
                                optstack.push(operation);
                            }else if(operation.equals(")")) {
                                directCal(optstack, numStack,true);
                            }else if(operation.equals("=")) {
                                directCal(optstack, numStack,false);
                                return numStack.pop().toString();
                            }else {
                                compareOpt_Cal(numStack, optstack, operation);
                            }
                        }
                    }
                }
            }
            
            if(numBuilder.length()>0) {
                numStack.push(new BigDecimal(numBuilder.toString()));
            }
            directCal(optstack, numStack, false);
            return numStack.pop().toString();
            
            
        }
        
        //带xml参数的计算
        public static String Calc(String expression,String xml) throws MyException {
            
            //判断表达式是否为空
            if(expression==null||expression.equals("")) {
                throw new IllegalArgumentException("表达式不能为空!");
            }
            
            Matcher matcher = EXPRESSION_PATTERN.matcher(expression);
            if(!matcher.matches()){
                throw new IllegalArgumentException("表达式含有非法字符!");
            }
            
            expression = formatExpression(expression);
            isExpression(expression);
            
            Option option=JaxbUtil.convertToJavaBean(xml, Option.class);
            int op_num = 0;
            
            Stack<String> optstack = new Stack<>();
            Stack<BigDecimal> numStack = new Stack<>();
            StringBuilder numBuilder = new StringBuilder(16);
            
            for(int i=0;i<expression.length();i++) {
                char ch = expression.charAt(i);
                if(ch!=' ') {
                    if((ch>='0'&&ch<='9')||ch=='.') {
                        numBuilder.append(ch);
                    }else {
                        if(++op_num>option.getOperation_num())
                            throw new MyException("操作符个数超过设置最大个数!");
                        
                        if(numBuilder.length()>0) {
                            BigDecimal value = new BigDecimal(numBuilder.toString());
                            if(value.doubleValue()>option.getMax()||value.doubleValue()<option.getMin())
                                throw new MyException("数据超出设置范围!");
                            if(isNum(numBuilder.toString())==false) {
                                throw new MyException("表达式格式错误!————数字格式错误(错误数字:'"+numBuilder+"'");
                            }
                            numStack.push(value);
                            numBuilder.delete(0, numBuilder.length());
                        }
                        String operation = String.valueOf(ch);
                        if(optstack.empty()) {
                            optstack.push(operation);
                        }else {
                            if(operation.equals("(")) {
                                optstack.push(operation);
                            }else if(operation.equals(")")) {
                                directCal(optstack, numStack,true);
                            }else if(operation.equals("=")) {
                                directCal(optstack, numStack,false);
                                return String.format("%."+option.getPoint_long()+"f", numStack.pop());
                            }else {
                                compareOpt_Cal(numStack, optstack, operation);
                            }
                        }
                    }
                }
            }
            
            if(numBuilder.length()>0) {
                numStack.push(new BigDecimal(numBuilder.toString()));
            }
            directCal(optstack, numStack, false);
            return String.format("%."+option.getPoint_long()+"f", numStack.pop());
            
            
        }
        
        
        private static void compareOpt_Cal(Stack<BigDecimal> numstack,Stack<String> optstack,String operation) throws MyException {
            String topOpt = optstack.peek();
            int comp_val = getPriority(topOpt, operation);
            if(comp_val==-1||comp_val==0) {
                String opt = optstack.pop();
                BigDecimal num2 = numstack.pop();
                BigDecimal num1 = numstack.pop();
                BigDecimal result = calDouble(opt, num1, num2);
                numstack.push(result);
                if(optstack.empty()) {
                    optstack.push(operation);
                }else {
                    compareOpt_Cal(numstack, optstack, operation);
                }
            }else {
                optstack.push(operation);
            }
        }
        
        //判断两个操作符的优先级
        private static int getPriority(String op1,String op2) {
            return OP_PRIORITY_MAP.get(op2)-OP_PRIORITY_MAP.get(op1);
        }
        
        //两个数之间的运算,注意除数不能为0
        private static BigDecimal calDouble(String operation,BigDecimal num1,BigDecimal num2) throws MyException {
            BigDecimal result = new BigDecimal(0);
            switch (operation) {
            case "+":
                result = num1.add(num2);
                break;
            case "-":
                result = num1.subtract(num2);
                break;
            case "*":
                result = num1.multiply(num2);
                break;
            case "/":
                if(num2.equals(BigDecimal.ZERO)) {
                    throw new MyException("表达式格式错误!————数字格式错误(除数不能为0:'"+num1+"/"+num2+"')");
                }
                result = num1.divide(num2,10,BigDecimal.ROUND_DOWN);
                break;
            default:
                break;
            }
            return result;
        }
        
        //递归计算
        private static void directCal(Stack<String> opStack,Stack<BigDecimal> numStack,boolean haved) throws MyException {
            String opt = opStack.pop();
            BigDecimal num2 = numStack.pop();
            BigDecimal num1 = numStack.pop();
            BigDecimal result = calDouble(opt, num1, num2);
            
            numStack.push(result);
            
            if(haved) {
                if("(".equals(opStack.peek())) {
                    opStack.pop();
                }else {
                    directCal(opStack, numStack,haved);
                }
            }else {
                if(!opStack.empty()) {
                    directCal(opStack, numStack, haved);
                }
            }
        }
        
        //判断表达式的合法性(字符合法性)
        public static void isExpression(String expression) throws MyException {
            char pre=' ',cur=' ';
            int l_bracket_num=0,r_bracket_num=0;
            for(int i=0;i<expression.length();i++) {
                cur=expression.charAt(i);
                if(cur=='(') {
                    l_bracket_num++;
                }else if(cur==')') {
                    r_bracket_num++;
                }
                if(i>0) {
                    if(pre=='.'&&(cur=='.'||cur=='('||cur==')'||cur=='+'||cur=='-'||cur=='*'||cur=='/')) {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if((pre=='.'||pre=='('||pre==')'||pre=='+'||pre=='-'||pre=='*'||pre=='/')&&cur=='.') {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if((cur=='.'||cur==')'||cur=='+'||cur=='-'||cur=='*'||cur=='/')&&pre=='(') {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if((pre=='.'||pre=='('||pre=='+'||pre=='-'||pre=='*'||pre=='/')&&cur==')') {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if((pre=='+'||pre=='-'||pre=='*'||pre=='/')&&(cur=='+'||cur=='-'||cur=='*'||cur=='/')) {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if(cur=='='&&i!=expression.length()-1) {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if(cur=='='&&(pre=='+'||pre=='-'||pre=='*'||pre=='/'||pre=='(')) {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if(cur=='('&&(pre>='0'&&pre<='9')) {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }else if(pre==')'&&(cur>='0'&&cur<='9')) {
                        throw new MyException("表达式格式错误!————操作符格式错误(错误字符区域:'"+pre+cur+"')");
                    }
                }else {
                    if(cur=='/'||cur=='*'||cur=='.'||cur==')'||cur=='=')
                        throw new MyException("表达式格式错误!————表达式首字符不符合规范(错误字符:'"+cur+"'");
                }
                
                pre=cur;
            }
            if(l_bracket_num!=r_bracket_num)
                throw new MyException("表达式格式不正确!————存在不匹配的左右括号");
        }
        
        //判断表达式中数字的合法性
        public static boolean isNum(String num) {
            if(num.contains(".")) {
                for(int i=0;i<num.indexOf('.');i++){
                    if(i==0&&num.charAt(0)=='0'&&num.indexOf('.')>1) {
                        return false;
                    }
                }
            }else {
                if(num.charAt(0)=='0'&&num.length()>1)
                    return false;
            }
            return true;
        }
        
        //判断表达式的开头是否为+或-,如果是,则在其前面加上0方便操作
        public static String formatExpression(String expression) {
            String result="";
            if(expression.charAt(0)=='+'||expression.charAt(0)=='-')
                expression = "0"+expression;
            result = expression.replaceAll("[(]-", "(0-");
            result = result.replaceAll("[(][+]", "(0+");
            return result;
        }
        
        public static void main(String[] args) throws MyException {
            Option option = new Option();
            //设置最大字符数
            option.setOperation_num(10);
            //设置数值范围的最小值
            option.setMin(-1000);
            //设置数值范围的最大值
            option.setMax(1000);
            //设置结果保留的小数位
            option.setPoint_long(2);
            
            String xml = JaxbUtil.convertTomXml(option);
            
            //传入带xml参数的计算方法(如不需要直接去掉该参数即可)
            System.out.println(Calc("12+87",xml));
        }
    }

    最后就是一个bean

    package com.core.bean;
    
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Option {
        private int operation_num;
        private double min;
        private double max;
        private int point_long;
        public int getOperation_num() {
            return operation_num;
        }
        public void setOperation_num(int operation_num) {
            this.operation_num = operation_num;
        }
        public double getMin() {
            return min;
        }
        public void setMin(double min) {
            this.min = min;
        }
        public double getMax() {
            return max;
        }
        public void setMax(double max) {
            this.max = max;
        }
        public int getPoint_long() {
            return point_long;
        }
        public void setPoint_long(int point_long) {
            this.point_long = point_long;
        }
        
    }
    View Code
  • 相关阅读:
    p2394 精度题
    线性筛素数
    poj3468 线段树的懒惰标记
    逆元
    2018 Multi-University Training Contest 2
    2018 Multi-University Training Contest 1
    判断素数遇到的问题
    Mergeable Stack(链表实现栈)
    组合数
    poj2594 机器人寻找宝藏(最小路径覆盖)
  • 原文地址:https://www.cnblogs.com/ljpljm/p/13082262.html
Copyright © 2011-2022 走看看