結對編程(java實現)

来源:https://www.cnblogs.com/390-xie/archive/2019/10/17/11686734.html
-Advertisement-
Play Games

作者:謝偉潔3117004673 一、Github項目地址: https://github.com/jack-xie460/mytest.git 二、PSP表格 PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘) Planning 計劃 ...


作者:謝偉潔3117004673 

 

一、Github項目地址: https://github.com/jack-xie460/mytest.git

 

 

二、PSP表格

PSP2.1

Personal Software Process Stages

預估耗時(分鐘)

實際耗時(分鐘)

Planning

計劃

 

 

· Estimate

· 估計這個任務需要多少時間

 

 

Development

開發

 

 

· Analysis

· 需求分析 (包括學習新技術)

 

 

· Design Spec

· 生成設計文檔

 

 

· Design Review

· 設計覆審 (和同事審核設計文檔)

 

 

· Coding Standard

· 代碼規範 (為目前的開發制定合適的規範)

 

 

· Design

· 具體設計

 

 

· Coding

· 具體編碼

 

 

· Code Review

· 代碼覆審

 

 

· Test

· 測試(自我測試,修改代碼,提交修改)

 

 

Reporting

報告

 

 

· Test Report

· 測試報告

 

 

· Size Measurement

· 計算工作量

 

 

· Postmortem & Process Improvement Plan

· 事後總結, 並提出過程改進計劃

 

 

合計

 

 

 

 

 三、效能分析

生成10000道50以內的題目耗時340ms

統計10000道題目的對錯耗時119ms

速度還行!

 

 

 

 

四、實現過程

1.執行Produce類的start方法,程式開始運行,首先通過調用AmountOfNum類來判斷輸入指令是否正確,正確則返回題目數量,

通過調用BoundOfNum類來判斷輸入指令是否正確,正確則返回數值範圍的最大值;

2.Produce類調用Expression類隨機生成表達式,表達式又可通過子表達式和數值之間隨機結合,而子表達式又可通過數值隨機

結合,從而生成各種各樣的表達式;

3.生成的表達式傳入Calculate類,在Calculate中,通過調用houzhuiexp方法將傳入的中綴表達式轉化為尾碼表達式,然後調用

calculate方法調用遞歸方法recusion對尾碼表達式進行計算產生結果,;

4.將產生的題目和結果迴圈列印到相應的文件中;

5.執行Judge類來中的start方法進行對錯統計,首先通過調用ExtractPath類來判斷輸入指令是否正確,正確則返回題目文檔和

答案文檔的路徑,然後進行對錯統計。

6.各個類之間的協同合作圖:

 

 

 

 

 

五、代碼說明

 1.通過輸入指令生成題目文檔和答案文檔的代碼:

 1 package jieduitest01;
 2 
 3 import java.io.File;
 4 import java.io.FileWriter;
 5 import java.io.IOException;
 6 
 7 //控制台輸入命令,生成題目和答案放在對應文檔中
 8 public class Produce 
 9 {
10     
11     public static void start() throws IOException 
12     {
13         
14         File exerciseFile = new File("E:\\java\\結對作業\\src\\jieduitest01\\Exercises.txt");
15         File answerFile = new File("E:\\java\\結對作業\\src\\jieduitest01\\Answer.txt");
16         FileWriter writeToExercisefile =new FileWriter(exerciseFile);
17         FileWriter writeToAnswerfile =new FileWriter(answerFile);
18         
19         System.out.println("請輸入您想要生成的題目數量:(例如生成10道題目的格式:-n 10)");
20         while(!AmountOfExp.method()) {}
21         int amount = AmountOfExp.getAmount();
22         
23         System.out.println("請輸入您想要生成的題目中數值的範圍:(例如數值在10以內格式:-r 10)");
24         while (!BoundOfNum.method()) {}
25         int bound = BoundOfNum.getBound();
26         
27         String expression;
28         //可變數組存儲尾碼表達式用以查重
29         StringBuilder expressionSet = new StringBuilder();
30         //迴圈列印題目和答案
31         for(int i=0;i<amount;i++) 
32         {
33             expression =Expression.expression(bound);
34             Calculate cal = new Calculate(expression);
35             String houzhuiExp = cal.houzhuiexp();
36             
37             //產生的尾碼表達式與之前的重覆,即產生相同的題目
38             if(expression.indexOf(houzhuiExp)!=-1) 
39             {
40                 i--;
41                 continue;
42             }
43             
44             expressionSet.append(houzhuiExp);
45             String result = cal.calculate();
46             
47             //計算過程產生負數
48             if(result.equals("?")) 
49             {
50                 i--;
51                 continue;
52             }
53             
54             writeToExercisefile.write(i+1 +" 、" + expression + "="+"\n");
55             writeToAnswerfile.write(i+1 +"、" + result + "\n" );
56             
57         }    
58         writeToExercisefile.close();
59         writeToAnswerfile.close();
60     }
61 
62     
63 }    
View Code
 1 package jieduitest01;
 2 
 3 import java.util.Scanner;
 4 import java.util.regex.Matcher;
 5 import java.util.regex.Pattern;
 6 
 7 //使用 -n 參數控制生成題目的個數
 8 public class AmountOfExp
 9 {
10     
11     private static int amount;
12     
13     public static int getAmount() 
14     {
15         return amount;
16     }
17     
18     //判斷輸入指令,並從正確輸入指令中提取生成題目的數量
19     public static boolean method()
20     {
21         
22         Pattern p = Pattern.compile("(-)(n)(\\s+)(\\d{1,})");
23         Scanner scan = new Scanner(System.in);
24         String str = scan.nextLine();
25         Matcher m = p.matcher(str);
26         boolean bo = m.matches();
27         String[] sarr ;
28         if(!bo) 
29             System.out.println("您輸入的格式不合法,請按照格式重新輸入,例如:-n 10");
30         else 
31         { 
32             sarr = str.split("\\s+");
33             amount = Integer.parseInt(sarr[1]);
34         }
35         return bo;
36     }
37 
38 }
View Code

 

 1 package jieduitest01;
 2 
 3 import java.util.Scanner;
 4 import java.util.regex.Matcher;
 5 import java.util.regex.Pattern;
 6 
 7 //使用 -r 參數控制題目中數值範圍
 8 public class BoundOfNum 
 9 {
10 
11     private static int bound;
12     
13     public static int getBound()
14     {
15         return bound;
16     }
17     
18     //判斷輸入指令,並從輸入指令中提取題目中數值的範圍
19     public static boolean method()
20     {
21         
22         Pattern p = Pattern.compile("-r\\s+\\d+");
23         Scanner scan = new Scanner(System.in);
24         String str = scan.nextLine();
25         String[] sarr ;
26         Matcher m = p.matcher(str);
27         boolean bo = m.matches();
28         if(!bo) 
29             System.out.println("您輸入的格式不合法,請按照格式重新輸入,例如:-r 10");
30         else 
31         { 
32             sarr = str.split("\\s+");
33             bound = Integer.parseInt(sarr[1]);
34         }    
35         return bo;
36     }
37     
38 }
View Code

 

 1 package jieduitest01;
 2 
 3 import java.util.Random;
 4 
 5 //生成表達式
 6 public class Expression 
 7 {
 8     
 9     static Random ran=new Random();
10     
11     public static String expression(int bound) 
12     {
13         
14         String ziexp1 = null,ziexp2 = null;
15         
16         //概率結合不同的子表達式
17         int i = ran.nextInt(4);
18         switch(i) 
19         {
20         
21         case 0:
22             ziexp1 = RandomNum.nextNumber(bound);
23             ziexp2 = RandomNum.nextNumber(bound);
24             break;
25         case 1:
26             ziexp1 = RandomNum.nextNumber(bound);
27             ziexp2 = SubExpression.ziepression(bound);
28             break;
29         case 2:
30             ziexp1 = SubExpression.ziepression(bound);
31             ziexp2 = RandomNum.nextNumber(bound);
32             break;
33         case 3:
34             ziexp1 = SubExpression.ziepression(bound);
35             ziexp2 = SubExpression.ziepression(bound);
36             break;
37         default :
38         }
39         
40         String operater = operater();
41         String exp = ziexp1 +" "+operater+" "+ ziexp2;
42         return exp;
43     }
44 
45     
46     public static String operater()
47     {
48     
49         int opnum = ran.nextInt(4);
50         switch(opnum)
51         {
52         
53         case 0:
54             return "+";
55         case 1:
56             return "-";
57         case 2:
58             return "×";
59         case 3:
60             return "÷";
61         }
62         return null;
63     }    
64     
65 }
View Code

 

2.將生成的表達式計算出結果的代碼(用到波蘭表達式,即尾碼表達式):

  1 package jieduitest01;
  2 
  3 import java.util.HashMap;
  4 import java.util.Stack;
  5 
  6 //傳入生成的表達式計算出結果
  7 public class Calculate 
  8 {
  9     //用HashMap存儲運算符及其優先順序
 10      HashMap<String,Integer> opls;
 11      String str0;
 12      
 13      //構造函數,並初始化各個運算符的優先順序
 14      public Calculate(String str0) 
 15      {
 16          this.str0 = str0;
 17          if(opls==null) 
 18          {
 19              opls = new HashMap<String,Integer>(4);
 20                 opls.put("+",0);
 21                 opls.put("-",0);
 22                 opls.put("×",1);
 23                 opls.put("÷",1);
 24          }
 25      }
 26 
 27     //將中綴表達式轉化成尾碼表達式
 28     public String houzhuiexp() 
 29     {
 30         //出去空格符
 31         String str = str0.replace(" ","");
 32         //將中綴表達式分割放入數組
 33         String[] strArray = split(str);
 34         //尾碼表達式存儲棧
 35         Stack<String> houzhuiSta = new Stack<String>();
 36         //臨時棧
 37         Stack<String> temStack = new Stack<String>();
 38         
 39         for(String src:strArray) 
 40         {
 41             //將操作數直接壓入尾碼表達式的棧
 42             if(isNum(src))
 43                 houzhuiSta.push("("+src+")");
 44             else //操作數或者括弧
 45             {   
 46                 if(temStack.isEmpty()||src.equals("("))
 47                 {   //"("或臨時棧為空  
 48                     temStack.push(src);
 49                 }
 50                 else 
 51                 {   
 52                     if(isLow(temStack.peek(),src))
 53                     {
 54                         if(!src.equals(")"))
 55                         {   ////優先順序比臨時棧棧首值的低
 56                             while((!temStack.isEmpty())&&(isLow(temStack.peek(),src))) 
 57                             {
 58                                 houzhuiSta.push(temStack.pop());
 59                             }
 60                             temStack.push(src);
 61                         }else//為")" 
 62                         {   //臨時棧棧首的值不為"("
 63                             while((!temStack.isEmpty())&&!(temStack.peek().equals("("))) 
 64                             {
 65                                 houzhuiSta.push(temStack.pop());
 66                             }
 67                             //臨時棧棧首的值為"("
 68                             if((!temStack.isEmpty())&&(temStack.peek().equals("(")))
 69                             {    
 70                                 temStack.pop();
 71                             }
 72                         }
 73                     }else 
 74                     {
 75                         temStack.push(src);
 76                     }
 77                 }        
 78             }
 79         }
 80         //將臨時棧的剩餘值壓入尾碼棧
 81         while(!temStack.empty())
 82         {    
 83             houzhuiSta.push(temStack.pop());
 84         }
 85         //將尾碼棧中的尾碼表達式轉化為字元串返回
 86         StringBuilder sb1 = new StringBuilder();
 87         for(String str1:houzhuiSta) 
 88         {
 89             sb1.append(str1);
 90         }
 91         houzhuiSta.clear();
 92         return sb1.toString();
 93         
 94     }
 95     
 96     //分割表達式
 97     public String[] split(String str) 
 98     {
 99         
100         StringBuilder sb = new StringBuilder(str.length()*2);
101         for(char ch:str.toCharArray()) 
102         {
103             
104             if(ch=='+'||ch=='-'||ch=='×'||ch=='÷'||ch=='('||ch==')') 
105             {
106                 sb.append(",");
107                 sb.append(ch);
108                 sb.append(",");
109             }
110             else 
111             {
112                 sb.append(ch);
113             }
114         }
115         String src = sb.toString().replaceAll(",{2,}",",");
116         return src.split(",");
117         
118     }
119     
120     //分割尾碼表達式
121     public String[] splitHou(String str) 
122     {
123         
124         StringBuilder sb = new StringBuilder(str.length());
125         int i = 0;
126         for(char ch:str.toCharArray()) 
127         {
128             if(ch=='+'||ch=='-'||ch=='×'||ch=='÷') 
129             {
130                 sb.append(",");
131                 sb.append(ch);
132             }
133             else if(ch=='('||ch==')') 
134             {
135                 if(i>=1) 
136                 {
137                     sb.append(',');
138                 }
139             }
140             else
141             {
142                 sb.append(ch);
143                 i++;
144             }
145         }
146         String src = sb.toString().replaceAll(",{2,}",",");
147         return src.split(",");
148         
149     }
150     
151     //化簡分數
152     String simplify(String exResult) 
153     {
154         SplitFra sp = new SplitFra(exResult);
155         int numberater =sp.getNumberater();
156         int deno =sp.getDeno();
157         int comDiv = comDivisor(numberater,deno);
158         numberater /= comDiv;
159         deno /= comDiv;
160         int integer = numberater/deno;
161         int fration = numberater%deno;
162         if(integer == 0) 
163         {
164             return fration + "/" + deno;
165         }else if (fration == 0)
166         {
167             return integer+"";
168         }else
169         {    
170             return integer + "'" + fration + "/" +deno;
171         }
172     }
173     
174     //輾轉相除法求最大公約數
175     int comDivisor(int a,int b) 
176     {   int c = 1;
177         while(a % b != 0) 
178         {
179             c = a % b;
180             a = b;
181             b = c;
182         }
183         return b;
184     }
185     
186     //判斷是否是操作數
187      public boolean isNum(String str) 
188      {
189             for (char ch : str.toCharArray()) 
190             {
191                 if(ch=='+'||ch=='-'||ch=='×'||ch=='÷'||ch=='('||ch==')')
192                     return false;
193             }
194             return true;
195      }
196      
197      //比較優先順序
198      public boolean isLow(String pop, String str) 
199      {
200             if(str.equals(")"))
201                 return true;
202             if(opls.get(pop)==null||opls.get(str)==null)
203               return false;
204             return opls.get(pop)>=opls.get(str);
205      }   
206      
207      //調用遞歸方法利用尾碼表達式計算結果
208      public String calculate() 
209      {   
210          //尾碼表達式
211          String houhzhuiExp = houzhuiexp();
212          String[] strs = splitHou(houzhuiexp());
213          //調用遞歸得到結果
214          String exResult = recursion(strs);
215          //計算過程產生負數返回"?"
216          if(exResult.equals("?"))
217          {
218              return "?";
219          }
220          String result ;
221          //結果是分數,化簡
222          if(exResult.contains("/")) 
223          {
224             result = simplify(exResult);
225          }else 
226          {
227              result = exResult;
228          }     
229          return result;
230      }
231      //遞歸方法
232      public String recursion(String[] str) 
233      {   
234         //計算過程是否出現負數的標記 
235          boolean flag = false;
236          int nowlength = str.length;
237          if(str[str.length-1]==" ")
238          {     
239              nowlength = str.length-1;
240          }else if(str.length == 1) //尾碼表達式長度為1則遞歸結束返回結果
241          {
242              return str[0];
243          }
244          String[] nextstr = new String[nowlength-2];
245          for(int i = 2;i<nowlength;i++) 
246          {
247             
248              if(str[i].equals("+")||str[i].equals("-")||str[i].equals("×")||str[i].equals("÷")) 
249              {
250                   String num1 = str[i-2];
251                   String num2 = str[i-1];
252                   String operater = str[i];
253                   String result;
254                   switch(operater) 
255                   {
256                   case "+":
257                       result = Math.add(num1,num2)

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在谷歌瀏覽器中有4種方法調用IE瀏覽器。如下: 今天我們就來說一下使用chrome自定義協議打開ie瀏覽器並訪問指定頁面。 當然,有很多網友都寫過,我這裡就借花獻佛了。 使用方式: 添加註冊表 在桌面上建立一個openIE.reg(將txt改為reg)文件,點擊編輯打開,在裡面寫入如下內容來進行自定 ...
  • 核心:var grayLevel = r 0.299 + g 0.587 + b 0.114; 根據當前顏色的灰度判斷顏色深淺。 步驟一: 轉換色值為rgb格式 1. hex2rgb: hex格式是16進位,轉換為rgb其實就是16進位轉換為10進位,較為簡單。 步驟二: 獲取顏色灰色值: 之前已經 ...
  • 方式一:拿到value值以後 在你傳遞之前處理 function stripscript(value) { var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]") var rs ...
  • 場景 SpringCloud-服務註冊與實現-Eureka創建服務註冊中心(附源碼下載): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102535957 SpringCloud-服務註冊與實現-Eureka創建服務提供者(附源 ...
  • 簡單工廠模式 簡單工廠模式分為三種:普通簡單工廠、多方法簡單工廠、靜態方法簡單工廠。 普通工廠模式 最近看了老酒館電視劇,深深被陳懷海他們的情懷所感動,當然裡面也有很多的酒,比如扳倒井,悶倒驢,跑舌頭,吹破天,二閨女,枕頭親。我們以酒為例: 創建酒的介面: public interface Liqu ...
  • 官網:www.fhadmin.org 此項目為Springboot工作流版本 windows 風格,瀏覽器訪問操作使用,非桌面應用程式。 1.代碼生成器: [正反雙向](單表、主表、明細表、樹形表,快速開發利器) freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳 ...
  • 前言 今天我們來看策略模式【Stragety Pattern【行為型】】,這個模式還是比較好理解的。策略怎麼理解呢?一般是指:1. 可以實現目標的方案集合;2. 根據形勢發展而制定的行動方針和鬥爭方法;3. 有鬥爭藝術,能註意方式方法。總的來說呢就是針對一個目的的不同的方法集合。這裡要講的策略模式怎 ...
  • 單例模式 什麼是單例? 應用場景 代碼實現 餓漢式 中國古代神話中有女媧補天一說,現在天破了,我們去求女媧補天。 女媧用英語來說是 A Goddess In Chinese Mythology,意思就是神話中的女神,女媧是獨一無二的,現在我們就建一個女神類Goddess。 神話中,我們都是女媧造出來 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...