1.題目要求
題目1: 咱們在剛開始上課的時候介紹過一個小學四則運算自動生成程序的例子,請實現它,要求:java
- 可以自動生成四則運算練習題
- 能夠定製題目數量
- 用戶能夠選擇運算符
- 用戶設置最大數(如十之內、百之內等)
- 用戶選擇是否有括號、是否有小數
- 用戶選擇輸出方式(如輸出到文件、打印機等)
- 最好能提供圖形用戶界面(根據本身能力選作,以完成上述功能爲主)
2.分工
本次個人結對對象是王肖男,在做業的完成過程當中,咱們交換領航員和駕駛員的角色。本次做業的主要總體設計思路由我提出;在圖形界面的部分,我做爲領航員,王肖男做爲駕駛員;在算式生成的部分,王肖男做爲領航員,我做爲駕駛員;在文件操做部分,我做爲領航員,王肖男做爲駕駛員。git
3.我所負責的部分代碼的思路
3.1算式生成部分
在該部分,要根據傳入的信息產生符合用戶要求的四則運算式。 代碼以下:github
package ppp; import java.util.ArrayList; import java.util.Iterator; import java.util.Random; public class CreateList { private StringBuffer[] operator = new StringBuffer[4]; private boolean createBrackets = true;//生成括號 private boolean createMD = true;//生成乘除 private boolean createDecimal = true;//是否包含小數 private int maxNumber = 10;//最大值 private ArrayList<StringBuffer> arrOperator; private ArrayList<StringBuffer> arrNumber; private ArrayList<StringBuffer> arrDemo; //"乘除","小數","括號","最大值" public ArrayList<StringBuffer> create(String MD, String pointNum, String brackets,String maxNum) { if(pointNum == "no") createDecimal = false; if(brackets == "no") createBrackets = false; if(MD == "no") createMD = false; maxNumber = Integer.parseInt(maxNum); operator[0] = new StringBuffer("+"); operator[1] = new StringBuffer("-"); operator[2] = new StringBuffer("*"); operator[3] = new StringBuffer("/"); arrOperator= new ArrayList<StringBuffer>(); arrNumber = new ArrayList<StringBuffer>(); arrDemo = new ArrayList<StringBuffer>(); createOperator(); if(createDecimal) addDecimal(); else addInteger(); if(createBrackets) addBrackets(); Merge(); return arrDemo; } public void createOperator() { Random ra = new Random(); int pointer = 0; int l = 4; if(!createMD) l = 2; int length = 2+(int)ra.nextInt(4); for(int i=0;i<length;++i) { pointer =ra.nextInt(l); if (i!=0&&operator[pointer]==arrOperator.get(i-1)) i--; else arrOperator.add(operator[pointer]); } } public void addInteger() { int i=0; Random ra = new Random(); int d = ra.nextInt(maxNumber); arrNumber.add(new StringBuffer(Integer.toString(d))); for(StringBuffer sb:arrOperator) { int m = createInteger(i,sb); arrNumber.add(new StringBuffer(Integer.toString(m))); ++i; } } public void addDecimal() { Random ra = new Random(); int d = ra.nextInt(maxNumber-1)+1; arrNumber.add(new StringBuffer(Integer.toString(d))); double flag = 0; for(StringBuffer sb:arrOperator) { flag = ra.nextDouble(); if(flag<0.7) { arrNumber.add(new StringBuffer(Integer.toString(ra.nextInt(maxNumber-1)+1))); }else { StringBuffer st = new StringBuffer(); st.append(ra.nextInt(maxNumber)); st.append('.'); st.append(ra.nextInt(maxNumber)); arrNumber.add(st); } } } public void Merge() { Iterator<StringBuffer> it1 = arrOperator.iterator(); Iterator<StringBuffer> it2 = arrNumber.iterator(); for(;it1.hasNext();) { arrDemo.add(it2.next()); arrDemo.add(it1.next()); } arrDemo.add(it2.next()); } private int createInteger(int i,StringBuffer sb) { Random ra = new Random(); if(sb==operator[3]) { int num = Integer.parseInt(arrNumber.get(i).toString()); if(num == 0) return ra.nextInt(maxNumber)+1; for(int j = num-1;j>0;--j) if(num%j == 0) return j; } return ra.nextInt(maxNumber)+1; } public void addBrackets() { int tempI; double tempD; int i = 0; boolean jump = false; for(StringBuffer sb:arrNumber) { tempD = Double.parseDouble(sb.toString()); tempI = (int)tempD; if((tempD-tempI)<0.00000001&&(tempI>1)) { String s = String.valueOf(tempD); for(int t=0;t<s.length();++t) if(s.charAt(t)!='.') { departInteger(i); jump = true; break; } if(jump) break; } ++i; } } public void departInteger(int i) { Random ra = new Random(); int l = 4; if(!createMD) l=2; int pointer = ra.nextInt(l); int number1 = 0; int number2 = 0; StringBuffer s = arrNumber.get(i); int element = Integer.parseInt((s.toString())); if(pointer == 0) { number1 = ra.nextInt(element); number2 = element - number1; StringBuffer newS = new StringBuffer("("+Integer.toString(number1)+"+"+Integer.toString(number2)+")"); arrNumber.remove(i); arrNumber.add(i,newS); }else if(pointer == 2) { for(number1=element;number1>0;--number1) if(element%number1 == 0) { number2 = element/number1; break; } StringBuffer newS = new StringBuffer("("+Integer.toString(number1)+"*"+Integer.toString(number2)+")"); arrNumber.remove(i); arrNumber.add(i,newS); }else if(pointer == 3) { for(int j=maxNumber-1;j>=1;++j) if(j%element==0) { number1 = j; break; } number2 = number1/element; StringBuffer newS = new StringBuffer("("+Integer.toString(number1)+"/"+Integer.toString(number2)+")"); arrNumber.remove(i); arrNumber.add(i,newS); } } }
3.2代碼的編寫思路
- 算式的各部分生成順序: 在屢次嘗試後,我採用了先生成運算符序列,再生成運算數序列,最後根據要求選擇添加括號。這種方式可以解決在不產生小數且須要添加括號的要求下運算結果不包含小數的問題,根據數學運算的規則,先計算括號中的算式,在運算中所有爲整數時,當括號及除法都不產生小數,整個算式的運算結果就不會產生小數。
- 容器選擇: 我選用的是ArrayList容器,用於存儲運算符序列,運算數序列。在完成用戶的算式生成要求後,再將兩個序列合併爲一個序列。而容器中存儲的數據類型爲StringBuffer,採用它的緣由是它相對於String類型的可變性,可以更容易地實現個人括號的添加的方法。
- 算符產生函數 將運算符生成爲一個數組,依據隨機數產生下標,組合成運算符序列。
- 生成小數 因爲隨機生成的double類型尾數較多,因此我採用了分別生成整數部分與小數部分再進行拼接的方法。
- 添加括號 該類中最複雜的部分是生成不含小數且含括號的算式。如果隨機添加括號,則可能引發運算順序改變而產生小數。因此在生成運算數序列時,將運算數序列的運算數分解爲一個帶括號的運算序列,這樣在運算順序改變時結果不會改變,即不產生小數。
3.3運行截圖
4.代碼地址
GitHub算法
5.總結
在本次任務中由我負責總體的規劃。在代碼編寫過程當中不斷改進,包括容器的選擇,用戶要求的實現順序等,使我意識到軟件工程思想的重要性,在過程當中遇到的問題讓我反思本身在總體規劃方面能力的欠缺。在從此,我會在這方面努力增強自身。數組
6.界面類及文件操做類的代碼審查表
<table> <caption>計算器算法審查表</caption><caption> </caption><tbody> <tr> <td width="300" height="19">重要性</td> <td width="100">激活</td> <td width="100">級別</td> <td width="900">檢查項</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">命名規則是否與所採用的規範保持一致?</td> </tr> <tr> <td bgcolor="gray" width="300" height="19">註釋</td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="900"> </td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 10</td> <td bgcolor="yellow" width="900">註釋是否較清晰且必要?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 10</td> <td width="900">複雜的分支流程是否已經被註釋?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 10</td> <td width="900">距離較遠的}是否已經被註釋?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 10</td> <td width="900">非通用變量是否所有被註釋?</td> </tr> <tr> <td width="300" height="19"></td> <td width="100">N</td> <td width="100"> 50</td> <td width="900">函數是否已經有文檔註釋?(功能、輸入、返回及其餘可選)</td> </tr> <tr> <td width="300" height="19"> 重要 </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 10</td> <td bgcolor="yellow" width="900">特殊用法是否被註釋?</td> </tr> <tr> <td bgcolor="gray" width="300" height="19">聲明、空白、縮進</td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="900"> </td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900"> 每行是否只聲明瞭一個變量?(特別是那些可能出錯的類型)</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 40</td> <td bgcolor="yellow" width="900">變量是否已經在定義的同時初始化?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 40</td> <td bgcolor="yellow" width="900">類屬性是否都執行了初始化?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">代碼段落是否被合適地以空行分隔?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 20</td> <td width="900">是否合理地使用了空格使程序更清晰?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">代碼行長度是否在要求以內?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">折行是否恰當?</td> </tr> <tr> <td bgcolor="gray" width="300" height="19">語句/功能分佈/規模</td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="900"> </td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">包含複合語句的{}是否成對出現並符合規範?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 20</td> <td width="900">是否給單個的循環、條件語句也加了{}?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">if/if-else/if-else if-else/do-while/switch-case語句的格式是否符合規範?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 40</td> <td bgcolor="yellow" width="900">單個變量是否只作單個用途?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">單行是否只有單個功能?(不要使用;進行多行合併)</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 40</td> <td bgcolor="yellow" width="900">單個函數是否執行了單個功能並與其命名相符?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">操做符++和— —操做符的應用是否複合規範?</td> </tr> <tr> <td bgcolor="gray" width="300" height="19">規模</td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="900"> </td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">單個函數不超過規定行數?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 100</td> <td bgcolor="yellow" width="900">縮進層數是否不超過規定?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 100</td> <td width="900">是否已經消除了全部警告?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 40</td> <td bgcolor="yellow" width="900">常數變量是否聲明爲final?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 80</td> <td bgcolor="yellow" width="900">對象使用前是否進行了檢查?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 80</td> <td width="900">局部對象變量使用後是否被複位爲NULL?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 70</td> <td bgcolor="yellow" width="900">對數組的訪問是不是安全的?(合法的index取值爲[0, MAX_SIZE-1])。</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">是否確認沒有同名變量局部重複定義問題?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">程序中是否只使用了簡單的表達式?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">全部判斷是否都使用了(常量==變量)的形式?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 80</td> <td width="900">是否每一個if-else if-else語句都有最後一個else以確保處理了全集?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 80</td> <td width="900">是否每一個switch-case語句都有最後一個default以確保處理了全集?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 80</td> <td bgcolor="yellow" width="900">for循環是否都使用了包含下限不包含上限的形式?(k=0; k<max)< td=""> </max)<></td></tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 40</td> <td bgcolor="yellow" width="900">XML標記書寫是否完整,字符串的拼寫是否正確?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 40</td> <td width="900">對於流操做代碼的異常捕獲是否有finally操做以關閉流對象?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100"> N</td> <td width="100"> 20</td> <td width="900">退出代碼段時是否對臨時對象作了釋放處理?</td> </tr> <tr> <td bgcolor="gray" width="300" height="19">可靠性(函數)</td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="900"> </td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 60</td> <td width="900">入口對象是否都被進行了判斷不爲空?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 60</td> <td width="900">入口數據的合法範圍是否都被進行了判斷?(尤爲是數組)</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 20</td> <td width="900">是否對有異常拋出的方法都執行了try...catch保護?</td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 80</td> <td bgcolor="yellow" width="900">是否函數的全部分支都有返回值?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 50</td> <td width="900">int的返回值是否合理?(負值爲失敗,非負值成功)</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 20</td> <td width="900">對於反覆進行了int返回值判斷是否認義了函數來處理?</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 60</td> <td bgcolor="yellow" width="900">關鍵代碼是否作了捕獲異常處理?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 60</td> <td width="900">是否確保函數返回CORBA對象的任何一個屬性都不能爲null?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 60</td> <td width="900">是否對方法返回值對象作了null檢查,該返回值定義時是否被初始化?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 60</td> <td width="900">線程處理函數循環內部是否有異常捕獲處理,防止線程拋出異常而退出?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 20</td> <td width="900">原子操做代碼異常中斷,使用的相關外部變量是否恢復先前狀態?</td> </tr> <tr> <td width="300" height="19">重要</td> <td width="100">N</td> <td width="100"> 100</td> <td width="900">函數對錯誤的處理是恰當的?</td> </tr> <tr> <td bgcolor="gray" width="300" height="19">可維護性</td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="100"> </td> <td bgcolor="gray" width="900"> </td> </tr> <tr> <td width="300" height="19">重要</td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 100</td> <td bgcolor="yellow" width="900">實現代碼中是否消除了直接常量?(用於計數起點的簡單常數例外)</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">是否消除了致使結構模糊的連續賦值?(如a= (b=d+c ))</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 20</td> <td width="900">是否每一個return前都要有日誌記錄?</td> </tr> <tr> <td width="300" height="19"> </td> <td width="100">N</td> <td width="100"> 20</td> <td width="900">是否有冗餘判斷語句?(如:if (b) return true; else return false;)</td> </tr> <tr> <td width="300" height="19"> </td> <td bgcolor="yellow" width="100">Y</td> <td bgcolor="yellow" width="100"> 20</td> <td bgcolor="yellow" width="900">是否把方法中的重複代碼抽象成私有函數?</td> </tr> </tbody> </table>安全