运算公式



import java.util.*;


public class FuncUtil {


    //校验表达式
    public static Map<String, Object> checkFunc(String expression) {
        Map<String, Object> map = new HashMap<String, Object>();
        String str = formatFunc(expression);
        String reg = "^[A-Z()&+-]+$";
        map.put("expression", str);
        map.put("isvalid", str.matches(reg));
        return map;
    }


    //表达式格式化
    private static String formatFunc(String expression) {
        return expression.replaceAll("(", "(").replaceAll(")", ")")
                  .replaceAll(" ", "").replaceAll(" ", "").replaceAll("&&", "&")
                  .toUpperCase();
    }


    public static List<String> cal(String expression, Map<String, List<String>> dataMap) throws Exception {
        Stack<OperatorEnum> opStack = new Stack<OperatorEnum>();
        Stack<List<String>> dataStack = new Stack<List<String>>();


        char[] charArr;
        int length = (charArr = expression.toCharArray()).length;
        char value;
        OperatorEnum stackOp;
        OperatorEnum currOp;


        for (int i=0; i<length;) {
            value = charArr[i];


            //数据,操作符入栈
            //操作符为字母
            if (Character.isLetter(value)) {
                String key = String.valueOf(value);
                try {
                    List<String> item = (List)dataMap.get(key);
                    dataStack.push(new ArrayList<String>(item));
                    ++i;
                } catch (Exception e) {
                    throw new ExpressionFormatException("集合" + key +"不存在");
                }
            } else if (OperatorEnum.isSimpleOperator(String.valueOf(value))){
                //考虑括号和优先级
                //左括号或者当前操作数优先级比上一个操作数优先级高,操作数入栈,不做计算
                if (!OperatorEnum.RIGHT_BRACKET.equals(currOp = OperatorEnum.getOperator(String.valueOf(value)))
                        && (opStack.isEmpty() || OperatorEnum.LEFT_BRACKET.equals(stackOp = opStack.peek())
                        || stackOp.getPriority() < currOp.getPriority())) {
                    opStack.push(currOp);
                    ++i;
                } else {
                    singleCal(opStack, dataStack);
                    if (OperatorEnum.RIGHT_BRACKET.equals(currOp)) {
                        while(!OperatorEnum.LEFT_BRACKET.equals(opStack.peek())) {
                            singleCal(opStack, dataStack);
                        }
                        if (!OperatorEnum.LEFT_BRACKET.equals(opStack.pop())) {
                            throw new ExpressionFormatException("解析异常");
                        }
                        ++i;
                    }
                }
            } else {
                throw new ExpressionFormatException("公式计算异常");
            }
        }


        while (!opStack.isEmpty()) {
            singleCal(opStack, dataStack);
        }
        return dataStack.pop();
    }


    private static void singleCal(Stack<OperatorEnum> opStack, Stack<List<String>> dataStack) throws ExpressionFormatException{
        OperatorEnum currOp = opStack.peek();
        if (OperatorEnum.LEFT_BRACKET.equals(currOp)) {
            return ;
        }
        opStack.pop();
        List<String> firstList = null;
        List<String> secondList = null;
        if (currOp.getParaNum() == 1) {
            firstList = dataStack.pop();
        } else {
            secondList = dataStack.pop();
            firstList = dataStack.pop();
        }
        List<String> result;
        switch(currOp) {
            case ADD: result = add(firstList,secondList); break;
            case SUB: result = sub(firstList, secondList); break;
            case AND: result = and(firstList, secondList); break;
            default: throw new ExpressionFormatException("未实现的运算符[" + currOp + "]");


        }
        dataStack.push(result);
    }


    private static List<String> add(List<String> firstList, List<String> secondList) {


        if (firstList == null) {
            return new ArrayList<String>();
        }
        if (secondList == null) {
            return firstList;
        }


        firstList.removeAll(secondList);
        firstList.addAll(secondList);


        return firstList;
    }


    private static List<String> sub(List<String> firstList, List<String> secondList) {
        if (firstList == null) {
            return new ArrayList<String>();
        }
        if (secondList == null) {
            return firstList;
        }
        firstList.removeAll(secondList);


        return firstList;
    }


    private static List<String> and(List<String> firstList, List<String> secondList) {
        if (firstList == null || secondList == null) {
            return new ArrayList<String>();
        }


        firstList.retainAll(secondList);


        return firstList;
    }


}




public enum OperatorEnum {


    ADD("+", 2, 1, "加法"),


    SUB("-", 2, 1, "减法"),


    AND("&", 2, 1, "交集"),


    LEFT_BRACKET("(", 0, Integer.MAX_VALUE, "左括号"),


    RIGHT_BRACKET(")", 0, Integer.MAX_VALUE, "右括号");


    private String expression;
    private int paraNum;
    private int priority;
    private String desc;


    OperatorEnum(String expression, int paraNum, int priority, String desc) {
        this.expression = expression;
        this.paraNum = paraNum;
        this.priority = priority;
        this.desc = desc;
    }


    //是否简单二元运算
    public static boolean isSimpleOperator(String expression) {
        return ADD.expression.equals(expression) || SUB.expression.equals(expression) || AND.expression.equals(expression)
                || LEFT_BRACKET.expression.equals(expression) || RIGHT_BRACKET.expression.equals(expression);
    }


    public static OperatorEnum getOperator(String expression) {
        for (OperatorEnum operator : OperatorEnum.values()) {
            if (operator.expression.equals(expression)) {
                return operator;
            }
        }
        return null;
    }


    public String getExpression() {
        return expression;
    }


    public void setExpression(String expression) {
        this.expression = expression;
    }


    public int getParaNum() {
        return paraNum;
    }


    public void setParaNum(int paraNum) {
        this.paraNum = paraNum;
    }


    public int getPriority() {
        return priority;
    }


    public void setPriority(int priority) {
        this.priority = priority;
    }


    public String getDesc() {
        return desc;
    }


    public void setDesc(String desc) {
        this.desc = desc;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值