java解析公式“(@1+@12)*@10“并计算

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class StringTest {
    public static void main(String[] args) {
        String str = "(@1+@12)*@10";
        //1、提取数字
        String s = str.replaceAll("[^0-9]", ",");
        List<String> strings = Arrays.asList(s.split(","));
        strings = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

        //2、去除@提取表达式
        Pattern p = Pattern.compile("[\\d.]");
        Matcher m = p.matcher(str);
        while (m.find()) {
            if (!"".equals(m.group()))
                str = str.replace(m.group(), "");
        }
        String[] split = str.split("@");
        //3、拼接新的表达式
        String newd = "";
        for (int i = 0; i < split.length; i++) {
            for (int j = 0; j < strings.size(); j++) {
                if (i == j) {
                    newd =  newd + split[i] +strings.get(j);
                }
            }
        }
        String value = CalculateUtils.calculate(CalculateUtils.strCast(newd));
        System.out.println(value);
    }
}

结果:
在这里插入图片描述
声明:此处引用工具类:https://blog.csdn.net/xuhuanchao/article/details/5536179

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 实现对字符串表达式进行简单的包括函数的运算。
 */
public class CalculateUtils {
    /**
     * 定义运算符
     */
    public static List<String> lc = new ArrayList<String>();
    static {
        lc.add("+");
        lc.add("-");
        lc.add("*");
        lc.add("/");
    }
    /**
     * 定义逻辑运算符
     */
    public static List<String> lj = new ArrayList<String>();
    static {
        lj.add(">");
        lj.add("<");
        lj.add("=");
        lj.add("!");
    }
    /**
     * int数组注释,第一个标识:0自带函数 1自定义函数;第二个标识:参数个数
     */
    public static Map<String, int[]> funMap = new HashMap<String, int[]>();
    static {
        // 自带函数,可利用反射机制
        funMap.put("abs", new int[] { 0, 1 });
        funMap.put("acos", new int[] { 0, 1 });
        funMap.put("asin", new int[] { 0, 1 });
        funMap.put("atan", new int[] { 0, 1 });
        funMap.put("cbrt", new int[] { 0, 1 });
        funMap.put("ceil", new int[] { 0, 1 });
        funMap.put("cos", new int[] { 0, 1 });
        funMap.put("cosh", new int[] { 0, 1 });
        funMap.put("exp", new int[] { 0, 1 });
        funMap.put("expm1", new int[] { 0, 1 });
        funMap.put("floor", new int[] { 0, 1 });
        funMap.put("log", new int[] { 0, 1 });
        funMap.put("log10", new int[] { 0, 1 });
        funMap.put("log1p", new int[] { 0, 1 });
        funMap.put("random", new int[] { 0, 1 });
        funMap.put("rint", new int[] { 0, 1 });
        funMap.put("round", new int[] { 0, 1 });
        funMap.put("signum", new int[] { 0, 1 });
        funMap.put("sin", new int[] { 0, 1 });
        funMap.put("sinh", new int[] { 0, 1 });
        funMap.put("sqrt", new int[] { 0, 1 });
        funMap.put("tan", new int[] { 0, 1 });
        funMap.put("tanh", new int[] { 0, 1 });
        funMap.put("max", new int[] { 0, 2 });
        funMap.put("min", new int[] { 0, 2 });
        // 自定义函数
        funMap.put("if", new int[] { 1, 3 });
        funMap.put("mod", new int[] { 1, 2 });
        funMap.put("int", new int[] { 1, 1 });
    }

    /**
     * 公式初始化转换
     *
     * @param str
     * @return 处理过的计算客串
     */
    public static String strCast(String str) {
        str = str.toLowerCase();// 去除空格,变小写
        /*Pattern p=Pattern.compile("[//u4e00-//u9fa5]");//匹配中文
        Matcher m = p.matcher(str);*/

        if (str == null ? true : str.length() == 0)
            return "0";
        /*if(m.find()){
            return "0";
        }*/
        if (!checkFormula(str))
            return "0";
        str = str.replaceAll("//*-", "**");
        str = str.replaceAll("-//*", "**");
        str = str.replaceAll("/-", "//");
        str = str.replaceAll("-/", "//");
        str = str.replaceAll("//+-", "-");
        str = str.replaceAll("-//+", "-");
        str = str.replaceAll("-", "-");
        str = str.replaceAll("//*//*", "*-");
        str = str.replaceAll("//", "/-");
        str = str.replaceAll(" ", "");
        return str;
    }

    /**
     * 检查公式中括号出现次数是否正确
     *
     * @param formulaStr
     * @return 公式中的括号是否成对
     */
    public static boolean checkFormula(String formulaStr) {
        boolean flag = true;
        int count = 0;
        for (int i = 0; i < formulaStr.length(); i++) {
            String s = String.valueOf(formulaStr.charAt(i));
            if ("(".equals(s))
                count++;
            else if (")".equals(s))
                count--;
        }
        flag = count == 0;
        return flag;
    }

    /**
     * 分割函数
     *
     * @param str
     * @param bs
     * @return 分割后的客串
     */
    public static String[] spliteFun(String str, String bs) {
        List<String> list = new ArrayList<String>();
        String bds = "";
        int bracket = 0;
        int len = str.length();
        for (int i = 0; i < len; i++) {
            String s = String.valueOf(str.charAt(i));
            if ("(".equals(s)) {
                bracket++;
            } else if (")".equals(s)) {
                bracket--;
            }

            if (bracket == 0 && bs.equals(s)) {
                list.add(bds);
                bds = "";
                continue;
            }

            bds += s;
        }

        list.add(bds);

        String[] ss = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            ss[i] = list.get(i);
        }

        return ss;
    }

    /**
     * 用户自定义函数
     *
     * @param str
     * @param funStr
     * @return 处理用户自定义函数
     */
    public static String customFun(String str, String funStr) {
        String reval = "0";

        String[] gss = spliteFun(str, ",");
        if ("if".equals(funStr)) {
            if (compare(gss[0])) {
                reval = calculate(gss[1]);
            } else {
                reval = calculate(gss[2]);
            }
        } else if ("mod".equals(funStr)) {
            double d2 = new Double(calculate(gss[1]));
            if (d2 == 0)
                return reval;
            double d1 = new Double(calculate(gss[0]));
            reval = (d1 % d2) + "";
        } else if ("int".equals(funStr)) {
            reval = Math.floor(new Double(calculate(gss[0]))) + "";
        }
        return reval;
    }

    /**
     * 逻辑表达式判断
     *
     * @param str
     * @return true or false
     */
    public static boolean compare(String str) {
        boolean flag = false;
        boolean bs = false;
        int len = str.length();
        int bracket = 0;
        String ljbds = "";
        double d_left = 0;
        double d_right = 0;

        for (int i = 0; i < len; i++) {
            String s = String.valueOf(str.charAt(i));
            if ("(".equals(s)) {
                bracket++;
            } else if (")".equals(s)) {
                bracket--;
            }

            if (bracket == 0 && lj.contains(s)) {
                for (int j = i; j < len; j++) {
                    String ts = String.valueOf(str.charAt(j));
                    if (lj.contains(ts)) {
                        ljbds += ts;
                    } else {
                        bs = true;
                        break;
                    }
                }
            }
            if (bs)
                break;
        }

        String[] s = str.split(ljbds);
        d_left = new Double(calculate(s[0]));
        d_right = new Double(calculate(s[1]));

        if ("<".equals(ljbds)) {
            if (d_left < d_right)
                return true;
        } else if (">".equals(ljbds)) {
            if (d_left > d_right)
                return true;
        } else if ("=".equals(ljbds)) {
            if (d_left == d_right)
                return true;
        } else if (">=".equals(ljbds)) {
            if (d_left >= d_right)
                return true;
        } else if ("<=".equals(ljbds)) {
            if (d_left <= d_right)
                return true;
        } else if ("<>".equals(ljbds) || "!=".equals(ljbds)) {
            if (d_left != d_right)
                return true;
        }

        return flag;
    }

    /**
     * 递归调用运算
     *
     * @param str
     * @return String
     */
    public static String calculate(String str) {

        String reval = "";
        String bds = "";
        int bracket = 0;// 对应括号个数
        int pos = 0;
        boolean title = false;

        if (str.substring(0, 1).equals("-")) {
            str = str.substring(1);
            title = true;
        }

        int len = str.length();

        for (int i = 0; i < len; i++) {
            String s = String.valueOf(str.charAt(i));
            pos = i;
            bracket = 0;
            if (!lc.contains(s)) {// 如果没遇到运算符
                if ("(".equals(s)) {// 如果遇到左括号
                    if (funMap.containsKey(bds)) {// 如果左括号前是函数
                        for (int j = i + 1; j < len; j++) {// 从左括号后开始循环
                            pos++;// 累计移动字符位数
                            String ts = String.valueOf(str.charAt(j));// 单个字符
                            // reval+=ts;
                            if ("(".equals(ts))// 如果是左括号累计
                                bracket++;
                            else if (")".equals(ts)) {// 如果是右括号进行减少
                                bracket--;
                                if (bracket == -1) {// 如果是-1,标识括号结束
                                    reval = reval.substring(0, reval.length()
                                            - bds.length());// 重新获得去掉函数头的表达式
                                    reval += funCalculate(str.substring(i + 1,
                                            j), bds);// 表达式加上函数结果,形成新表达式
                                    i = pos;// 计数器增加
                                    bds = "";// 函数头清空
                                    break;// 退出本次循环
                                }
                            }
                        }
                    } else {// 如果是普通运算
                        for (int j = i + 1; j < len; j++) {
                            pos++;
                            String ts = String.valueOf(str.charAt(j));
                            if ("(".equals(ts))
                                bracket++;
                            else if (")".equals(ts)) {
                                bracket--;
                                if (bracket == -1) {
                                    reval += calculate(str
                                            .substring(i + 1, pos));
                                    i = pos;
                                    bds = "";
                                    break;
                                }
                            }
                        }
                    }
                } else {// 累加总表达式和最后一个运算数(或函数)
                    bds += s;
                    reval += s;
                }
            } else {// 遇到运算符最后一个运算数(或函数)清空
                bds = "";
                reval += s;
            }
        }

        if (title)
            reval = "-" + reval;
        return szys(reval);
    }

    /**
     * 函数运算
     *
     * @param gs
     * @param funStr
     * @return String
     */
    public static String funCalculate(String gs, String funStr) {
        String rval = "0";
        if (funMap.containsKey(funStr)) {
            int[] csi = funMap.get(funStr);
            try {
                if (csi[0] == 0) {// java内部函数,通过反射调用
                    Class[] cs = new Class[csi[1]];
                    Object[] objs = new Object[csi[1]];
                    String[] gss = zlcs(gs);
                    for (int i = 0; i < csi[1]; i++) {
                        cs[i] = double.class;
                        objs[i] = new Double(calculate(gss[i]));
                    }
                    Class cls = Class.forName("java.lang.Math");
                    Method m = cls.getMethod("abs", cs);
                    rval = String.valueOf(m.invoke(cls, objs));
                } else if (csi[0] == 1) {// 自定义函数
                    rval = customFun(gs, funStr);
                }
            } catch (Exception e) {

            }
        }

        return rval;
    }

    /**
     * 公式里的参数分割
     *
     * @param str
     * @return String[]
     */
    public static String[] zlcs(String str) {
        int len = str.length();
        boolean flag = true;
        String tstr = "";

        for (int i = 0; i < len; i++) {
            String s = String.valueOf(str.charAt(i));
            if ("(".equals(s)) {
                flag = false;
            } else if (")".equals(s)) {
                flag = true;
            }
            if (flag && ",".equals(s)) {
                tstr += "@";
            } else {
                tstr += s;
            }
        }

        return tstr.split("@");

    }

    /**
     * 四则运算表达式处理
     *
     * @param gs
     * @return String
     */
    public static String szys(String gs) {
        gs = gs + "+0"; // 因为下面的计算是遇到符号才进行,所以多加入一个计算符号,不影响值.
        String c1 = "";// 第一个运算符号
        String c2 = "";// 第二个运算符号
        String s1 = "";// 第一个运算数
        String s2 = "";// 第二个运算数
        String s3 = "";// 第三个运算数

        int len = gs.length();
        for (int i = 0; i < len; i++) {
            String s = String.valueOf(gs.charAt(i));// 获得该位置字符并转换成字符串做比较

            if (lc.contains(s)) { // 如果是运算符号
                if (c1.length() == 0)// 如果第一个运算符号为空,加入
                    c1 = s;
                else if (c2.length() == 0) {// 否则,如果第二个运算符号为空,加入
                    c2 = s;// 第二个运算符号
                    if ("+".equals(c2) || "-".equals(c2)) {// 如果第二个运算符号级别低,那么进行计算
                        s1 = _4zys(s1, c1, s2);// 第一个和第二个数计算
                        c1 = c2;// 保存第二个运算符,其他为空
                        c2 = "";
                        s2 = "";
                    }
                } else {// 上述都保存过
                    if ("+".equals(s) || "-".equals(s)) {// 如果第三个运算符级别低,进行运算
                        s2 = _4zys(s2, c2, s3);// 先算第二三个数,保存至第二个
                        s1 = _4zys(s1, c1, s2);// 再算第一二个,保存至第一个
                        c1 = s;// 保存当前运算符,其他为空
                        s2 = "";
                        c2 = "";
                        s3 = "";
                    } else {// 如果第三个运算符级别高
                        s2 = _4zys(s2, c2, s3);// 先算第二三个数,保存至第二个
                        c2 = s;// 前面不动,保存运算符
                        s3 = "";
                    }
                }
            } else if (s1.length() > 0 && c1.length() > 0 && c2.length() == 0) {// 如果第一个数,第一个运算符已保存,第二个运算符未保存,保存第二哥数
                s2 += s;
            } else if (c1.length() == 0) {// 如果没有运算符,保存第一个数
                s1 += s;
            } else if (s1.length() > 0 && s2.length() > 0 && c1.length() > 0
                    && c2.length() > 0) {// 如果第一二个数和运算符都有,保存第三个数
                s3 += s;
            }
        }
        return s1;
    }

    /**
     * 基本四则运算
     *
     * @param c1
     *            运算数1
     * @param s1
     *            运算符(加减乘除)
     * @param c2
     *            运算数2
     * @return String
     */
    public static String _4zys(String c1, String s1, String c2) {
        String reval = "0";

        try {
            double ln = Double.valueOf(c1).doubleValue();
            double rn = Double.valueOf(c2).doubleValue();
            if ("+".equals(s1)) {
                return (ln + rn) + "";
            } else if ("-".equals(s1)) {
                return (ln - rn) + "";
            } else if ("*".equals(s1)) {
                return (ln * rn) + "";
            } else if ("/".equals(s1)) {
                if (rn == 0)
                    return reval;
                else
                    return (ln / rn) + "";
            }
        } catch (Exception e) {
        } finally {
        }

        return reval;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖小八

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值