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

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

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

    大魚

    Java實現(xiàn)四則運算的解析收藏

    前些天,在項目里面在做OLAP模塊,其中一個自定義配置部分,里面需要用到根據(jù)配置的四則運算公式(字符串型),計算公式的結(jié)果。
    于是在網(wǎng)上搜索了一番,終于有所啟發(fā)。但是也感慨網(wǎng)上很多的例子并不完整,讓我冒著訪問惡意網(wǎng)頁的風險,四處瀏覽。遂將我自己的實現(xiàn)寫在這里,供大家參考討論。
    此實現(xiàn)方法主要是參考了機械工業(yè)出版社出版的《數(shù)據(jù)結(jié)構(gòu)、算法與應(yīng)用——C++語言描述》(2000年1月出版)當中,第5章——堆棧,第169頁,5.5應(yīng)用——5.5.1括號匹配的例子,使用Java編寫完成。
    JVM版本為JDK6 Update1.
    因為在處理四則運算的時候最麻煩的邏輯主要是對括號內(nèi)預(yù)算的處理,特別是括號的嵌套。
    因此該算法主要的邏輯是,通過對括號位置的觀察,得出:從左至右的掃描一個字符串,那么每一個右括號將與最近遇到的那個未匹配的左括號相匹配。這和堆棧的后進先出的規(guī)則是一樣的。因此得到在掃描的過程當中,將每一個遇到的左括號進行壓棧,在出現(xiàn)右括號的時候,出棧。
    該解法相對于通過遞歸實現(xiàn)的解法,在時間復(fù)雜性上略好,并且實現(xiàn)出來的代碼更加清晰。
    以下為具體實現(xiàn)的代碼:
    package azurecube.common;
    import java.util.LinkedList;
    import java.util.ArrayList;
    public class FormulaCalculator {
     private boolean isRightFormat = true;
     
     public double getResult(String formula){
      double returnValue = 0;
      try{
       returnValue = doAnalysis(formula);
      }catch(NumberFormatException nfe){
       System.out.println("公式格式有誤,請檢查:" + formula);
      }catch(Exception e){
       e.printStackTrace();
      }
      if(!isRightFormat){
       System.out.println("公式格式有誤,請檢查:" + formula);
      }
      return returnValue;
     }
     private double doAnalysis(String formula){
      double returnValue = 0;
      LinkedList<Integer> stack = new LinkedList<Integer>();
      
      int curPos = 0;
      String beforePart = "";
      String afterPart = "";
      String calculator = "";
      isRightFormat = true;
      while(isRightFormat&&(formula.indexOf('(') >= 0||formula.indexOf(')') >= 0)){
       curPos = 0;
       for(char s : formula.toCharArray()){
        if(s == '('){
         stack.add(curPos);
        }else if(s == ')'){
         if(stack.size() > 0){
          beforePart = formula.substring(0, stack.getLast());
          afterPart = formula.substring(curPos + 1);
          calculator = formula.substring(stack.getLast() + 1, curPos);
          formula = beforePart + doCalculation(calculator) + afterPart;
          stack.clear();
          break;
         }else{
          System.out.println("有未關(guān)閉的右括號!");
          isRightFormat = false;
         }
        }
        curPos++;
       }
       if(stack.size() > 0){
        System.out.println("有未關(guān)閉的左括號!");
        break;
       }
      }
      if(isRightFormat){
       returnValue = doCalculation(formula);
      }
      return returnValue;
     }
     private double doCalculation(String formula) {
      ArrayList<Double> values = new ArrayList<Double>();
      ArrayList<String> operators = new ArrayList<String>();
      int curPos = 0;
      int prePos = 0;
      for (char s : formula.toCharArray()) {
       if (s == '+' || s == '-' || s == '*' || s == '/') {
        values.add(Double.parseDouble(formula.substring(prePos, curPos)
          .trim()));
        operators.add("" + s);
        prePos = curPos + 1;
       }
       curPos++;
      }
      values.add(Double.parseDouble(formula.substring(prePos).trim()));
      char op;
      for (curPos = operators.size() - 1; curPos >= 0; curPos--) {
       op = operators.get(curPos).charAt(0);
       switch (op) {
       case '*':
        values.add(curPos, values.get(curPos) * values.get(curPos + 1));
        values.remove(curPos + 1);
        values.remove(curPos + 1);
        operators.remove(curPos);
        break;
       case '/':
        values.add(curPos, values.get(curPos) / values.get(curPos + 1));
        values.remove(curPos + 1);
        values.remove(curPos + 1);
        operators.remove(curPos);
        break;
       }
      }
      for (curPos = operators.size() - 1; curPos >= 0; curPos--) {
       op = operators.get(curPos).charAt(0);
       switch (op) {
       case '+':
        values.add(curPos, values.get(curPos) + values.get(curPos + 1));
        values.remove(curPos + 1);
        values.remove(curPos + 1);
        operators.remove(curPos);
        break;
       case '-':
        values.add(curPos, values.get(curPos) - values.get(curPos + 1));
        values.remove(curPos + 1);
        values.remove(curPos + 1);
        operators.remove(curPos);
        break;
       }
      }
      return values.get(0).doubleValue();
     }
    }

    posted on 2010-04-21 14:01 大魚 閱讀(1642) 評論(1)  編輯  收藏 所屬分類: j2se

    評論

    # re: Java實現(xiàn)四則運算的解析收藏 2013-05-24 16:46 lrklx

    2000+600/3-300*2+0.1 = 1599.9 ????  回復(fù)  更多評論   

    主站蜘蛛池模板: 亚洲日韩av无码| 相泽亚洲一区中文字幕| 色偷偷女男人的天堂亚洲网 | 美女羞羞喷液视频免费| 成人免费视频网址| 亚洲国产精品18久久久久久| 韩国欧洲一级毛片免费| 亚洲AV无码国产精品永久一区| 在线免费观看中文字幕| 亚洲av无码日韩av无码网站冲 | 国产2021精品视频免费播放| 亚洲熟妇无码爱v在线观看| 99在线精品视频观看免费| 亚洲成A人片在线播放器| 精品免费国产一区二区| 理论片在线观看免费| 浮力影院亚洲国产第一页| 免费观看91视频| 亚洲国产精品综合久久久| 女人张开腿等男人桶免费视频| 国产成人不卡亚洲精品91| 国产亚洲色视频在线| 亚洲大片免费观看| 亚洲AV无码资源在线观看| 国产成人亚洲综合无码| 96免费精品视频在线观看| 亚洲人成色4444在线观看| 亚洲精品美女久久久久99小说| 十九岁在线观看免费完整版电影| 精品亚洲AV无码一区二区| 啊v在线免费观看| 一区二区三区四区免费视频 | eeuss在线兵区免费观看| 亚洲av永久无码制服河南实里 | 色播精品免费小视频| 美女又黄又免费的视频| 亚洲综合在线成人一区| 免费国产精品视频| 99久久国产免费中文无字幕| 亚洲AV成人精品日韩一区| 亚洲AV本道一区二区三区四区 |