<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      軟工作業3:結對編程【四則運算】

      學生個人信息

      姓名 學號
      鄭耿杭 3121004978
      梁鴻俊 3121004956

      作業基本信息

      這個作業屬于哪個課程 軟件工程
      作業要求 結對編程
      作業目標 實現一個自動生成小學四則運算的程序

      Github

      https://github.com/lianghongjun/operation

      PSP表格

      PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
      Planning 計劃 30 20
      Estimate 估計這個任務需要多少時間 30 15
      Development 開發 180 200
      Analysis 需求分析 120 90
      Design Spec 生成設計文檔 10 10
      Design Review 設計復審 10 10
      Coding Standard 代碼規范 5 5
      Design 具體設計 50 60
      Coding 具體編碼 80 80
      Code Review 代碼復審 30 20
      Test 測試 40 50
      Reporting 報告 10 10
      Test Report 測試報告 10 10
      Size Measurement 計算工作量 20 20
      Postmortem & Process Improvement Plan 事后總結, 并提出過程改進計劃 10 10
      合計 625 610

      設計實現過程

      項目目錄

      image
      1.Arithmetic:算術類(子類:運算符類Operator,操作數類Operand,括號類Bracket)
      2.Brackets:括號類
      3.Equation:表達式類
      4.Operand:操作數類
      5。Operator:運算符類
      6.FileUtils:文件工具類,包括將內容寫入指定路徑文件和從指定路徑文件讀取成表達式數組的方法

      代碼說明

      1.關鍵代碼
      filter()
      說明:用于過濾重復的表達式
      思路:
      1.按順序層層篩選,由于轉換成后綴表達式,不用考慮括號
      2.先去除運算過程含負數的
      3.先比較結果
      4.比較表達式是否一樣
      5.再比較包含的運算符是否相同
      6.比較第一次運算的兩數是否只是交換位置

      點擊查看代碼
      /**
           * 用來過濾重復表達式,按順序層層篩選,由于轉換成后綴表達式,不用考慮括號
           * 1. 先去除運算過程含負數的
           * 2. 先比較結果
           * 3. 比較表達式是否一樣
           * 4. 再比較包含的運算符是否相同
           * 5. 比較第一次運算的兩數是否只是交換位置
           *
           * @param list 要過濾的表達式數組
           * @return 過濾完成的表達式
           */
          public static List<Equation> filter(List<Equation> list) {
              for (int i = 0; i < list.size(); i++) {
                  Equation equation = list.get(i);
                  // 如果運算過程含負數,則跳過
                  if (equation.isOf()) {
                      list.remove(equation);
                      //remove會整體前移
                      i--;
                      continue;
                  }
                  // 和整個list比較
                  // 標簽方便下面層層嵌套能直接goto出來
                  flag:
                  for (int o = 0; o < list.size(); o++) {
                      Equation toCompare = list.get(o);
                      // 刪除后有空位,要跳過
                      if (toCompare == null) {
                          continue;
                      }
                      // 遇到自己就跳過
                      if (equation == toCompare) {
                          continue;
                      }
                      // 先比較結果
                      if (Math.abs(equation.getResult() - toCompare.getResult()) < 0.000001) {
                          // 結果相同,看是否完全一樣
                          if (equation.equals(toCompare)) {
                              list.remove(equation);
                              // remove會整體前移
                              i--;
                              break flag;
                          }
                          // 再比較運算符
                          List<Arithmetic> postfix1 = equation.getPostfix();
                          List<Arithmetic> postfix2 = toCompare.getPostfix();
                          List<Operator> operators1 = equation.getOperators();
                          List<Operator> operators2 = toCompare.getOperators();
                          // 有不同運算符就保留
                          if (operators1.size() != operators2.size()) {
                              break flag;
                          }
                          for (int j = 0; j < operators1.size(); j++) {
                              if (operators1.get(j) != operators2.get(j)) {
                                  break flag;
                              }
                          }
      
                          // 運算符相同,只比較第一次計算的兩數字是否交換位置
                          // 找到第一個運算符,取前兩個數字
                          List<Operand> operands1 = new ArrayList<>();
                          List<Operand> operands2 = new ArrayList<>();
                          for (int j = 0; j < postfix1.size(); j++) {
                              if (postfix1.get(j) instanceof Operator) {
                                  operands1.add((Operand) postfix1.get(j - 1));
                                  operands1.add((Operand) postfix1.get(j - 2));
                                  break;
                              }
                          }
                          for (int j = 0; j < postfix1.size(); j++) {
                              if (postfix2.get(j) instanceof Operator) {
                                  operands2.add((Operand) postfix2.get(j - 1));
                                  operands2.add((Operand) postfix2.get(j - 2));
                                  break;
                              }
                          }
                          // 比較兩對數字
                          if ((operands1.get(0).equals(operands2.get(0)) || operands1.get(0).equals(operands2.get(1))) &&
                                  (operands1.get(1).equals(operands2.get(0)) || operands1.get(1).equals(operands2.get(1)))) {
                              list.remove(equation);
                              //remove會整體前移
                              i--;
                          }
                          // 兩對數字不相同,保留
                          break;
                      } else {
                          //結果不一樣,保留
                          break;
                      }
                  }
      
              }
              return list.stream().toList();
          }
      

      generate()
      說明:用于生成隨機表達式
      思路:通過傳參確定此次生成中包含的操作數數量、運算符數量、括號數量、數的范圍,然后隨機new出各對象,交替拼接操作數和運算符,最后隨機添加括號

      點擊查看代碼
      /**
           * 用來生成隨機表達式
           *
           * @param operandNo  操作數數量
           * @param operatorNo 運算符數量
           * @param bracketsNo 括號數量
           * @param lowEnd     生成表達式中操作數和真分數分母范圍的下限
           * @param upEnd      生成表達式中操作數和真分數分母范圍的上限
           * @return 生成的表達式
           */
          public static Equation generate(int operandNo, int operatorNo, int bracketsNo
                  , int lowEnd, int upEnd) {
              Random r = new Random();
              int scope = upEnd - lowEnd;
              List<Arithmetic> arithmetics = new ArrayList<>();
              List<Operand> operands = new ArrayList<>();
              List<Operator> operators = new ArrayList<>();
              List<Brackets> brackets = new ArrayList<>();
      
              try {
                  for (int i = 0; i < operandNo; i++) {
                      // 操作數類型 自然數(0),真分數(1)
                      int type = r.nextInt(10) % 2;
                      if (0 == type) {
                          // 生成隨機整數
                          operands.add(new Operand(type, r.nextInt(scope) + lowEnd + ""));
                      } else {
                          // 生成真分數
                          int denominator = r.nextInt(scope) + lowEnd + 1;
                          // 分子 > 0
                          int numerator = r.nextInt(denominator - 1) + 1;
                          String str = numerator + "/" + denominator;
                          operands.add(new Operand(type, str));
                      }
                  }
      
                  for (int i = 0; i < operatorNo; i++) {
                      // 除去等號
                      int index = r.nextInt(4) + 1;
                      operators.add(Operator.getByIndex(index));
                  }
      
                  for (int i = 0; i < bracketsNo; i++) {
                      brackets.add(Brackets.getByIndex(0));
                      brackets.add(Brackets.getByIndex(1));
                  }
      
                  for (int i = 0; i < operands.size(); i++) {
                      if (operands.get(i) != null) {
                          arithmetics.add(operands.get(i));
                      }
                      if (i == operands.size() - 1) {
                          break;
                      }
                      if (operators.get(i) != null) {
                          arithmetics.add(operators.get(i));
                      }
                  }
      
              } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
              return new Equation(arithmetics);
          }
      

      infixToPostfix()
      說明: 將中綴表達式轉換成后綴表達式
      思路:
      無括號:
      1.掃描中綴表達式的每一個字符,將數字入列;
      2.遇到運算符,??諘r直接進棧,棧頂非空時,運算符優先級大于棧頂元素才進棧,
      否則棧頂元素退棧入列,當前運算符再進棧;
      3.依次進行直至所有字符操作完畢
      有括號:
      1.掃描中綴表達式的每一個字符,將數字入列;
      2.遇到運算符,??諘r直接進棧,棧頂非空時,運算符優先級大于棧頂元素才進棧,
      否則棧頂元素退棧入列,當前運算符再進棧;
      3.遇到左括號,直接進棧,左括號后面的運算符直接進棧,直至遇到右括號;
      4.遇到右括號時,將棧頂元素依次退棧入列,直到遇到左括號,將左括號退棧,符號操作移動下一位
      5.重復以上操作,直至所有字符操作完成。

      點擊查看代碼
       /**
           * 將中綴表達式轉換為后綴表達式
           *
           * @return 返回轉換結果
           */
          public List<Arithmetic> infixToPostfix() {
              Stack<Arithmetic> stack = new Stack<>();
              List<Arithmetic> postfix = new ArrayList<>();
              for (int start = 0; start < infix.size(); start++) {
                  // 如果是運算符
                  if (infix.get(start).priority > 0) {
                      // 棧空 或 "(" 或 符號優先級>棧頂符號 且 不為")" 直接進棧
                      if (stack.isEmpty() || infix.get(start).priority == 3 ||
                              ((infix.get(start).priority > stack.peek().priority) && infix.get(start).priority < 4)) {
                          stack.push(infix.get(start));
                      } else if (!stack.isEmpty() && infix.get(start).priority <= stack.peek().priority) {
                          // 棧非空 且 符號優先級≤棧頂符號, 出棧; 直到 棧為空 或 遇到了"("
                          while (!stack.isEmpty() && infix.get(start).priority <= stack.peek().priority) {
                              if (stack.peek().priority == 3) {
                                  stack.pop();
                                  break;
                              }
                              postfix.add(stack.pop());
                          }
                          stack.push(infix.get(start));
                      } else if (infix.get(start).priority == 4) {
                          // ")",依次出棧直到空?;蛴龅降谝粋€"(",此時"("出棧
                          while (!stack.isEmpty()) {
                              if (stack.peek().priority == 3) {
                                  stack.pop();
                                  break;
                              }
                              postfix.add(stack.pop());
                          }
      
                      }
                  } else if (infix.get(start).priority == -1) {
                      postfix.add(infix.get(start));
                  }
              }
              while (!stack.isEmpty()) {
                  postfix.add(stack.pop());
              }
              return postfix;
          }
      

      測試結果

      代碼隨機生成10000條計算式
      image

      代碼隨機生成10000條計算式結果
      image

      代碼隨機生成計算式
      image

      計算式計算結果
      image

      計算結果統計
      image

      效能分析

      image
      image

      消耗最大的函數

      用于去除重復的函數:Equation.filter()
      因為里面用了許多邏輯判斷和嵌套循環,時間復雜度高,隨生成數量提高而呈冪次增長

      posted @ 2023-09-26 16:17  一夢見浮生  閱讀(88)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 网友偷拍视频一区二区三区| 亚洲首页一区任你躁xxxxx| 久久国产成人精品av| 18禁免费无码无遮挡网站| 97人妻成人免费视频| 免费费很色大片欧一二区| 2021国产精品视频网站| 成人网站免费观看永久视频下载| 久热这里有精品免费视频| 亚洲一区精品伊人久久| 欧美videosdesexo吹潮| 国产-第1页-浮力影院| 看全色黄大黄大色免费久久| 亚洲国产精品综合久久20| 亚洲国产午夜精品福利| 午夜视频免费试看| 国内精品免费久久久久电影院97| 国产一二三五区不在卡| 视频一区视频二区在线视频| 亚洲乱码一二三四区国产| 久久蜜臀av一区三区| 女人张开腿让男人桶爽| 丁香婷婷综合激情五月色| 老司机精品成人无码av| 久久国产乱子伦免费精品无码| 精品无码专区久久久水蜜桃| 亚洲各类熟女们中文字幕| 成人拍拍拍无遮挡免费视频| 太深太粗太爽太猛了视频| av天堂亚洲天堂亚洲天堂| 老子午夜精品无码| 国产一区二区不卡精品视频| 中文字幕日韩人妻一区| 亚洲AV天天做在线观看| 国产精品免费第一区二区| 国产精品三级在线观看无码| 亚洲综合伊人五月天中文| 亚洲欧美高清在线精品一区二区 | 一区二区亚洲人妻精品| 婷婷五月综合丁香在线| 搡老熟女老女人一区二区|