<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java愛好者

    一個堅定的Java愛好者,歡迎和我討論
    隨筆 - 7, 文章 - 8, 評論 - 6, 引用 - 0
    數據加載中……

    一個計算表達式的類,供參考

    package cn.com.worksoft.util.expression;

    import java.util.Arrays;

    import cn.com.worksoft.util.log.LogFactory;
    import cn.com.worksoft.util.log.Logger;

    /**
    *
    * @author XING
    *
    * Create time 2004-12-2 16:52:48
    *
    * 本類的運算邏輯是 分為以下幾個步驟:
    * 1、格式化所輸入的算式(去掉所有空格,+-符號前面如果沒有數字就補0,×/符號前面如果沒有數字就補1,^~符號后面如果沒有數字就補2,其它如果出現前后缺少的情況就報錯)
    * 2、獲得的算式串,如A; 3、獲取所有運算符號,尋找第一個需要運算的符號,基本規則是,找到最里層的(),然后在其內部找,^~ > /* > +-
    * ,同類型的就從做至右運算; 4、獲取該運算符號的兩端變量,進行運算得出結果,將結果回填回去; 5、取得了新的運算串,存入A;
    * 6、重復2直到A中沒有運算符號為止; 7、得到結果。
    *
    * 更改所生成類型注釋的模板為 窗口 > 首選項 > Java > 代碼生成 > 代碼和注釋
    */
    public final class TExpression {
    public final static String ADD = "\\\\+";

    public final static String DECREASE = "\\\\-";

    public final static String[] DefaultVars = new String[]
    {
    "+",
    "-",
    "*",
    "/",
    "^",
    "~", };

    public final static String DIVIDE = "/";

    public final static String FU = "GXFU";

    public final static String LBRACKET = "\\\\(";

    public final static String MULTIPLY = "\\\\*";

    public final static String PERCENT = "%";

    public final static String POWER = "\\\\^";

    public final static String RBRACKET = "\\\\)";

    public final static String SQRT = "~";

    private final static Logger gLogger = LogFactory.defaultFacotry()
    .createNewLogger();

    /**
    * 將arg0數組,完全加在arg1的后面。
    *
    * @param arg0
    * @param arg1
    * @return
    */
    private static int[] addAll(int[] arg0, int[] arg1) {
    int[] arg = new int[arg0.length + arg1.length];
    for (int i = 0; i < arg0.length + arg1.length; i++) {
    if (i < arg0.length)
    arg[i] = arg0[i];
    else
    arg[i] = arg1[i - arg0.length];
    }
    return arg;
    }

    /**
    * 檢查括號是否正確使用。
    *
    * @param arg
    * @return
    */
    private static boolean CheckBracket(String arg) {
    boolean bln = true;
    if (SubStrCount(arg, "(") != SubStrCount(arg, ")")) {
    bln = false;
    }
    if (bln) {
    int[] lbracket = indexOf(arg, "(");
    int[] rbracket = indexOf(arg, ")");
    int length = lbracket.length;
    // new ErrPrintArray(System.err).printArray(lbracket);
    for (int i = 0; i < length; i++) {
    bln &= lbracket[i] < rbracket[i];
    }
    }

    return bln;
    }

    /**
    * 檢查表達式,并返回最終合格得表達式結果,如果無法返回合格得結果,將拋出異常。
    *
    * @param arg
    * @throws Exception
    * @return
    */
    private static String CheckTExpression(String arg) throws Exception {
    // / 檢查符號前后是否存在空缺。
    arg = Trim(arg);
    // / 將%修改成/100的運算符。
    arg = arg.replaceAll(TExpression.PERCENT, "/100");
    if (!CheckBracket(arg))
    throw new Exception("括號沒有匹配或者使用不當,請檢查!");
    // / 在)(之間增加*符號。
    arg = TrimBracket(arg);
    // / 如果-號開頭,那么就在前面增加一個FU
    if (arg.substring(0, 1).equals("-")) {
    arg = TExpression.FU + arg.substring(1, arg.length());
    }
    // / 如果+號開頭,那么就去掉+號
    if (arg.substring(0, 1).equals("-")) {
    arg = arg.substring(1, arg.length());
    }
    // / 如果*/號開頭,那么前面加一個1
    else if (arg.substring(0, 1).equals("*")
    || arg.substring(0, 1).equals("/")) {
    arg = arg.substring(1, arg.length());
    } else if (arg.substring(0, 1).equals("^")) {
    throw new Exception("~符號不能用在公式開頭的位置!");
    } else if (arg.substring(0, 1).equals("^")) {
    throw new Exception("∧符號不能用在公式開頭的位置!");
    }
    return arg;
    }

    public static String Do(String expression, boolean showProcess)
    throws Exception {
    String testStr = expression;
    /**
    * 檢查字符串。
    */
    String aa = null;
    try {
    aa = CheckTExpression(testStr);
    } catch (Exception e) {
    gLogger.error(e.getMessage(), e);
    e.printStackTrace();
    }
    try {
    String[] bb = TExpression.getVars(aa, DefaultVars);
    int i = 0;
    // 如果操作完的結果跟操作前相同,說明不需要繼續運算
    // 增加i,避免死循環。
    while (bb.length != 0 && i < 10000) {
    aa = doOperate(aa);
    if (showProcess) {
    gLogger.info(aa);
    }
    bb = TExpression.getVars(aa, DefaultVars);
    if (!isNaN(TrimAllBracket(aa))) {
    aa = TrimAllBracket(aa);
    break;
    }
    i++;
    }
    aa = TrimAllBracket(aa);
    } catch (Exception e) {
    gLogger.error(e.getMessage(), e);
    e.printStackTrace();
    }
    return aa;
    }

    /**
    * 對整個公式進行單步運算。
    *
    * @param arg
    * @return
    * @throws Exception
    */
    private static String doOperate(String arg) throws Exception {
    String leftRLT = "";
    String rightRLT = "";
    String rlt = arg;
    int[] rkfs = TExpression.indexOf(rlt, new String[]
    { ")", });
    int[] lkfs = TExpression.indexOf(rlt, new String[]
    { "(", });
    // 找到第一個)符號。
    // // 如果一個都沒有找到,那么直接對整個公式進行操作。
    if (rkfs.length == 0) {
    leftRLT = "";
    rightRLT = "";
    rlt = arg;
    }
    // // 否則,取()中間的內容,進行操作。
    else {
    int firstRkf = rkfs[0];
    // System.out.println(arg.substring(firstRkf - 1, firstRkf + 2));
    // 找到與第一個)符號對應的(
    int containsLkf = lkfs[0];
    for (int i = 1; i < lkfs.length; i++) {
    if (lkfs[i] > firstRkf)
    break;
    else
    containsLkf = lkfs[i];
    }
    // System.out.println(arg.substring(containsLkf - 1, containsLkf +
    // 2));
    // 取得中間的串,并取得兩端的串。
    leftRLT = rlt.substring(0, containsLkf);
    rightRLT = rlt.substring(firstRkf + 1, rlt.length());
    rlt = rlt.substring(containsLkf + 1, firstRkf);
    }
    // System.out.println(rlt);
    // 重新檢查語法
    rlt = CheckTExpression(rlt);

    String[] vars = getVars(rlt, DefaultVars);
    String[] ops = getOperates(rlt, DefaultVars);
    if (1 == 2) {
    return null;
    }
    // 找到^~的運算
    // // 如果存在^符號而且不存在~,或者存在^符號而且存在~符號并且^符號在~符號之前,那么就先運算^符號。
    else if ((rlt.indexOf("^") != -1 && rlt.indexOf("~") == -1)
    || (rlt.indexOf("^") != -1 && rlt.indexOf("~") != -1 && rlt
    .indexOf("^") < rlt.indexOf("~"))) {
    int index = indexOf(ops, "^");
    String op = TExpression.POWER;
    rlt = doOperate1(rlt, vars[index], vars[index + 1], op);
    rlt = "(" + rlt + ")";
    }
    // // 如果存在~符號而且不存在^,或者存在~符號而且存在^符號并且~符號在^符號之前,那么就先運算~符號。
    else if ((rlt.indexOf("~") != -1 && rlt.indexOf("^") == -1)
    || (rlt.indexOf("~") != -1 && rlt.indexOf("^") != -1 && rlt
    .indexOf("~") < rlt.indexOf("^"))) {
    int index = indexOf(ops, "~");
    if (vars[index + 1].equals("0"))
    throw new Exception("【嚴重錯誤】:開方數不能為零");
    String op = TExpression.SQRT;
    rlt = doOperate1(rlt, vars[index], vars[index + 1], op);
    rlt = "(" + rlt + ")";
    }
    // 如果沒有找到,那么找*/的運算
    else if ((rlt.indexOf("*") != -1 && rlt.indexOf("/") == -1)
    || (rlt.indexOf("*") != -1 && rlt.indexOf("/") != -1 && rlt
    .indexOf("*") < rlt.indexOf("/"))) {
    int index = indexOf(ops, "*");
    String op = TExpression.MULTIPLY;
    rlt = doOperate1(rlt, vars[index], vars[index + 1], op);
    rlt = "(" + rlt + ")";
    }
    // // 如果存在~符號而且不存在^,或者存在~符號而且存在^符號并且~符號在^符號之前,那么就先運算~符號。
    else if ((rlt.indexOf("/") != -1 && rlt.indexOf("*") == -1)
    || (rlt.indexOf("/") != -1 && rlt.indexOf("*") != -1 && rlt
    .indexOf("/") < rlt.indexOf("*"))) {
    int index = indexOf(ops, "/");
    if (vars[index + 1].equals("0"))
    throw new Exception("【嚴重錯誤】:除數為零");
    String op = TExpression.DIVIDE;
    rlt = doOperate1(rlt, vars[index], vars[index + 1], op);
    rlt = "(" + rlt + ")";
    }
    // 如果沒有找到,那么找+-運算
    else if ((rlt.indexOf("+") != -1 && rlt.indexOf("-") == -1)
    || (rlt.indexOf("+") != -1 && rlt.indexOf("-") != -1 && rlt
    .indexOf("+") < rlt.indexOf("-"))) {
    int index = indexOf(ops, "+");
    String op = TExpression.ADD;
    rlt = doOperate1(rlt, vars[index], vars[index + 1], op);
    rlt = "(" + rlt + ")";
    }
    // // 如果存在~符號而且不存在^,或者存在~符號而且存在^符號并且~符號在^符號之前,那么就先運算~符號。
    else if ((rlt.indexOf("-") != -1 && rlt.indexOf("+") == -1)
    || (rlt.indexOf("-") != -1 && rlt.indexOf("+") != -1 && rlt
    .indexOf("-") < rlt.indexOf("+"))) {
    int index = indexOf(ops, "-");
    String op = TExpression.DECREASE;
    rlt = doOperate1(rlt, vars[index], vars[index + 1], op);
    rlt = "(" + rlt + ")";
    }
    // // 如果什么符號都沒有找到,說明該串是個單變量的串,直接去掉兩端的括號,返回。
    else {
    rlt = TrimAllBracket(rlt);
    }
    // 把運算結果替換到適當的位置,然后返回。
    return leftRLT + rlt + rightRLT;
    }

    /**
    * 執行某個運算操作。
    *
    * @param vars
    * @param ops
    * @param op
    *????????????如:"\\\\*"
    * @return
    * @throws Exception
    */
    private static String doOperate1(String rlt, String var1, String var2,
    String op) throws Exception {
    String tmp = var1 + op + var2;
    if (var1.indexOf(TExpression.FU) != -1) {
    var1 = var1.replaceAll(TExpression.FU, "-");
    }
    if (!isNaN(var1) && !isNaN(var2)) {
    // System.out.println(tmp);
    rlt = rlt.replaceFirst(tmp, "" + operate(var1, var2, op));
    }
    rlt = "(" + rlt + ")";
    return rlt;
    }

    /**
    * 返回int數組中最小的一個。 假設數組中不存在相等的情況。
    *
    * @param arg
    * @return
    */
    private static int getMin(int[] arg, int fromIndex) throws Exception {
    int i = arg[fromIndex];
    for (int k = fromIndex + 1; k < arg.length; k++) {
    if (arg[k] < i) {
    i = arg[k];
    } else if (arg[k] == i && arg[k] != Integer.MAX_value)
    throw new Exception("數組中存在相等的值,無法進行取最小值的運算。");
    }
    return i;
    }

    /**
    * 返回arg1中在arg2數組中存在的所有變量的順序組合。 如 (5*4+3) 返回 {*,+} ;
    *
    * @param arg1
    * @param arg2
    * @return
    * @throws Exception
    */
    private static String[] getOperates(String arg1, String[] arg2)
    throws Exception {
    int[] indexs = indexOf(arg1, arg2);
    String[] ops = new String[indexs.length];
    for (int i = 0; i < indexs.length; i++) {
    ops[i] = arg1.substring(indexs[i], indexs[i] + 1);
    }
    return ops;
    }

    /**
    * 返回arg1中在arg2數組中存在的所有變量兩端的變量的順序組合。 如 (5*4+3) 返回 {5,4,3} ;
    *
    * @param arg1
    * @param arg2
    * @return
    * @throws Exception
    */
    private static String[] getVars(String arg1, String[] arg2)
    throws Exception {
    // 去掉所有括號。
    arg1 = arg1.replaceAll(TExpression.LBRACKET, "");
    arg1 = arg1.replaceAll(TExpression.RBRACKET, "");

    int[] indexs = indexOf(arg1, arg2);
    // 如果沒有運算符,那么返回本身。
    if (indexs.length == 0)
    return new String[]
    { arg1 };
    String[] vars = new String[indexs.length + 1];
    for (int i = 0; i < indexs.length + 1; i++) {
    if (i == 0)
    vars[i] = arg1.substring(0, indexs[i]);
    else if (i == indexs.length)
    vars[i] = arg1.substring(indexs[i - 1] + 1, arg1.length());
    else
    vars[i] = arg1.substring(indexs[i - 1] + 1, indexs[i]);
    }
    return vars;
    }

    /**
    * 取得arg0中arg1的所有索引的值。
    *
    * @param arg0
    * @param arg1
    * @return
    */
    private static int[] indexOf(String arg0, String arg1) {
    int i = 0;
    int j = 0;
    int[] intArr = new int[SubStrCount(arg0, arg1)];
    while (arg0.indexOf(arg1, i) != -1) {
    intArr[j] = arg0.indexOf(arg1, i);
    i = intArr[j] + 1;
    j++;
    }
    return intArr;
    }

    /**
    * 取得arg0中arg1[]任意一個的所有索引的值。
    *
    * @param arg0
    * @param arg1
    * @return
    */
    private static int[] indexOf(String arg0, String[] arg1) throws Exception {
    int j = 0;
    // 取得arg1中所有成員最近的位置。
    int[] targets = new int[0];
    for (int k = 0; k < arg1.length; k++) {
    targets = addAll(targets, indexOf(arg0, arg1[k]));
    }
    Arrays.sort(targets);
    int[] intArr = new int[targets.length];
    while (j < intArr.length) {
    // 取得最近的一個成員的位置。
    int target = getMin(targets, j);
    intArr[j] = target;
    j++;
    }
    return intArr;
    }

    /**
    * 返回字串數組中,相關值對應的索引。
    *
    * @param arg1
    * @param arg2
    * @return
    */
    private static int indexOf(String[] arg1, String arg2) {
    for (int i = 0; i < arg1.length; i++) {
    if (arg2.equals(arg1[i]))
    return i;
    }
    return -1;
    }

    /**
    * 判斷是否為數字。
    *
    * @param arg
    * @return
    */
    private static boolean isNaN(String arg) {
    if (arg == null || arg.length() == 0)
    return true;
    try {
    Double.parseDouble(arg);
    } catch (NumberFormatException e) {
    return true;
    }
    return false;
    }

    public static void main(String[] args) {
    String testStr = "((-1-2%*3^(4)~2/1)(7+8)-9)()";
    testStr = "150*(200-600/40)*12+14*3-55+76+23/3+5+5";
    // testStr = "150*(200-600/40)*12+14*3-55+76+23/3+5+5/0";
    // System.err.println(testStr);

    // System.out.println("gdasfds");
    // System.out.println("gdasfds".replaceAll("k", ""));
    // System.out.println(SubStrCount(testStr, "~"));
    // System.out.println("gdass".indexOf("k"));
    // new
    // ErrPrintArray(System.err).printArray(TExpression.indexOf("fagaxa",
    // "a"));
    /**
    * 檢驗括號是否正確。
    */
    // boolean kk = CheckBracket(testStr);
    // System.err.println(kk);
    /**
    * 獲得字符串中所有變量的順序組合。
    */
    try {
    // new ErrPrintArray(System.err).printArray(TExpression.getVars(aa,
    // new String[] { "+", "-", "*", "/", "^", "~", }));
    } catch (Exception e) {
    e.printStackTrace();
    }
    /**
    * 正式測試功能。
    */
    try {
    testStr = Do(testStr, true);
    } catch (Exception e) {
    e.printStackTrace();
    }
    System.err.println(testStr);
    }

    /**
    * 直接運算得到結果。
    *
    * @param arg1
    * @param arg2
    * @param op
    * @return
    * @throws Exception
    */
    private static double operate(String arg1, String arg2, String op)
    throws Exception {
    double a1 = Double.parseDouble(arg1);
    double a2 = Double.parseDouble(arg2);
    if (op.equals(TExpression.ADD)) {
    return a1 + a2;
    } else if (op.equals(TExpression.DECREASE)) {
    return a1 - a2;
    } else if (op.equals(TExpression.MULTIPLY)) {
    return a1 * a2;
    } else if (op.equals(TExpression.DIVIDE)) {
    return a1 / a2;
    } else if (op.equals(TExpression.SQRT)) {
    return Math.pow(a1, 1 / a2);
    } else if (op.equals(TExpression.POWER)) {
    return Math.pow(a1, a2);
    }
    return 0d;
    }

    /**
    * 返回arg0中包含的arg1的個數。
    *
    * @param arg0
    * @param arg1
    * @return
    */
    private static int SubStrCount(String arg0, String arg1) {
    int i = 0;
    arg0 = Trim(arg0);
    i = arg0.length();
    arg1 = arg1.replaceAll("\\\\+", "\\\\" + ADD);
    arg1 = arg1.replaceAll("\\\\-", "\\\\" + TExpression.DECREASE);
    arg1 = arg1.replaceAll("\\\\*", "\\\\" + TExpression.MULTIPLY);
    arg1 = arg1.replaceAll("\\\\^", "\\\\" + TExpression.POWER);
    arg1 = arg1.replaceAll("\\\\(", "\\\\" + TExpression.LBRACKET);
    arg1 = arg1.replaceAll("\\\\)", "\\\\" + TExpression.RBRACKET);
    i = i - arg0.replaceAll(arg1, "").length();
    return i;
    }

    /**
    * 去除所有包含的空格。
    *
    * @param arg
    * @return
    */
    private static String Trim(String arg) {
    String rlt = "";
    rlt = arg.replaceAll(" ", "");
    return rlt;
    }

    /**
    * 去掉字串中的所有),(符號。
    *
    * @param arg
    * @return
    */
    private static String TrimAllBracket(String arg) {
    String rlt = arg;
    rlt = rlt.replaceAll("\\\\(", "");
    rlt = rlt.replaceAll("\\\\)", "");
    return rlt;
    }

    /**
    * 去掉多余的()符號; 在)(之間增加*符號;
    *
    * @param arg
    * @return
    */
    private static String TrimBracket(String arg) {
    String rlt = arg;
    rlt = rlt.replaceAll("\\\\(\\\\)", "");
    rlt = rlt.replaceAll("\\\\)\\\\(", "\\\\)\\\\*\\\\(");
    return rlt;
    }
    }

    posted on 2006-06-30 14:30 JStar 閱讀(1424) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 精品国产免费一区二区| 成年女人喷潮毛片免费播放| 中文字幕人成人乱码亚洲电影 | 又粗又大又长又爽免费视频| 亚洲综合偷自成人网第页色| 18勿入网站免费永久| 亚洲人成网国产最新在线| 成人a免费α片在线视频网站| 亚洲熟妇av午夜无码不卡| 国产精品久久香蕉免费播放| 国产亚洲精品欧洲在线观看| 亚洲精品无码成人片在线观看| 国产特黄一级一片免费| 亚洲s色大片在线观看| 最近免费中文字幕高清大全| 亚洲伊人久久大香线蕉啊| 思思99re66在线精品免费观看| 亚洲AV第一成肉网| 红杏亚洲影院一区二区三区| 久久免费公开视频| 亚洲中文字幕无码mv| 一本久到久久亚洲综合| a毛片在线免费观看| 亚洲熟妇av一区| 国产成人免费福利网站| AAAAA级少妇高潮大片免费看| 亚洲色图国产精品| 永久黄网站色视频免费观看| 一区二区三区免费电影| 亚洲黄色网站视频| 日本免费一本天堂在线| 国产在线精品观看免费观看| 中文字幕在线观看亚洲| 国产成人高清精品免费鸭子 | 一级毛片在线免费看| 亚洲人色大成年网站在线观看| 全黄性性激高免费视频| 一区二区在线免费观看| 成a人片亚洲日本久久| 亚洲第一AV网站| 午夜高清免费在线观看|