2016012015+小學四則運算練習軟件項目報告
1.倉庫地址:https://git.coding.net/FrrLolix/Calculate.git
2.需求分析:
①程序接受一個輸入的參數n後,隨機生成n道四則運算式,其中要保證生成的運算式的運算符在3-5個之間,同時程序對生成的運算式自動求解,結果和運算式一同輸出到result.txt文件中。
②因為面向對象是小學生,所以要保證生成的運算式中不出現負數和小數,運算的結果也不能出現負數和小數。
③程序需要判斷輸入的參數n是否合法,在不合法時要進行一定的處理。
④在原有的基礎上,生成的運算式隨機性的帶有括號和真分數。
3.功能設計:
①基本功能:
Ⅰ程序接收參數n,並對n的合法性作出判斷,若出現錯誤則提示。
Ⅱ自動生成n個運算式,並計算得出結果。
Ⅲ將計算後的結果與運算式一同存入txt文件中,保存在指定目錄下。
②擴展功能:
Ⅰ由於面向對象是小學生,因此數字在0-100之間。
Ⅱ隨機產生括號並保證括號的合法有效性。
Ⅲ加入分數運算式,並且保證計算前後都是真分數,且不可化簡。
4.設計實現:
①整體思路:
Ⅰ四則運算:首先產生5個隨機數和一個flag作為標誌,flag的值為隨機0-3,分別代表了不同數量的運算符和分數運算,確定了flag的值後,產生隨機的運算符將數字連接,構成運算式,再將運算符和數字拆分,利用兩個棧分別放置,將原本的運算式轉化成後綴表達式,從而進行計算,這也是逆波蘭表達式的計算方法。
Ⅱ帶括號計算:以3個運算符的計算為例,括號只能存在於前兩個數字和後兩個數字中,因此設置location這一參數,location為0時,括號在前,location為1時括號在後,分別進行討論,確定括號的位置,生成帶括號的運算式,在後續計算過程中,註意要增加括號的入棧和出棧操作。
Ⅲ真分數的計算:對於真分數,首先隨機產生0-100的某個數,然後隨機產生一個比剛剛生成的數小的數,通過輾轉相除法,生成真分數並輸出。
對於整體而言,我只使用了一個類,通過這個類來調用不同的方法解決問題。
②設計的函數:
Ⅰ構成3個運算數的運算式的方法: three(int n1,int n2,int n3)
Ⅱ構成4個運算數的運算式的方法:four(int n1,int n2,int n3,int n4)
Ⅲ構成5個運算數的運算式的方法:five(int n1,int n2,int n3,int n4,int n5)
Ⅳ實現計算的方法:Calculate(String s)
Ⅴ分式化簡的方法:gcd(int a,int b)
5.代碼詳情:
①生成表達式的算法:
Ⅰ這裏使用一個循環,flag用於判斷每次循環產生的結果,根據flag的不同調用不同的方法
for(i=0;i<n;i++){ int n1=ran.nextInt(100);//生成一個0-100的整數 int n2=ran.nextInt(100); int n3=ran.nextInt(100); int n4=ran.nextInt(100); int n5=ran.nextInt(100); int flag=ran.nextInt(4);//隨機生成一個0-3的整數,0表示3個運算數,1表示4個運算數,2表示5個運算數,3表示分數計算
Ⅱ此處是flag=3時,分數的生成方法
n1=1+ran.nextInt(101); n2=1+ran.nextInt(101); n3=1+ran.nextInt(101); int M,Z; int x1,x2,x3; x1=1+ran.nextInt(n1);//生成一個比分母n1小的分子,實現真分數 x2=1+ran.nextInt(n2);//生成一個比分母n2小的分子,實現真分數 x3=1+ran.nextInt(n3);//生成一個比分母n3小的分子,實現真分數 Z=x1*n2*n3+x2*n1*n3+x3*n1*n2; M=n1*n2*n3; String d=gcd(Z,M); s=x1+"/"+n1+"+"+x2+"/"+n2+"+"+x3+"/"+n3+"="+d; pw.write(s+"\r\n"); // \r\n即為換行
Ⅲ此處是3個運算符是運算式的生成方法,我在這裏進行了討論,加入了是否有括號的兩種情況,對於括號的位置進行設定,隨後輸出不同的結果,此處代碼較長,只展示一部分,詳細的可以在Coding.net上查詢
String s1= new String(); Random ran = new Random(); int sign1=ran.nextInt(4);//隨機生成一個0-3的整數,0表示加法,1表示減法,2表示乘法,3表示除法 int sign2=ran.nextInt(4); int sign3=ran.nextInt(2);//如果是1表示有括號,如果是0 表示無括號 int sign4=ran.nextInt(2);//如果是1表示產生分式,如果是0 表示整式。 if(sign1==sign2) { sign2=(sign1+1)%3;//保證兩個運算符不相同。 } if(sign3==0)//表示無括號 { //下面的過程為排除,除不整的,還有分母為0, if(sign2==3) { if(n3==0)//如果分母為0 n3=1+ran.nextInt(100);//隨機生成一個1-100的整數 while(n2%n3!=0) { n2=ran.nextInt(100); } }
②計算方法
Ⅰ計算方法我采用了逆波蘭表達式的算法,這一部分是之前困擾我最久的地方,起初想了許多方法來嘗試,但都有些繁瑣,實施起來並不是很容易,因此我也在其他博客上參考學習了許多,最終選定了逆波蘭表達式,逆波蘭表達式的思路為
1.遇到操作數:直接輸出(添加到後綴表達式中)
2.棧為空時,遇到運算符,直接入棧
3.遇到左括號:將其入棧
4.遇到右括號:執行出棧操作,並將出棧的元素輸出,直到彈出棧的是左括號,左括號不輸出。
5.遇到其他運算符:加減乘除:彈出所有優先級大於或者等於該運算符的棧頂元素,然後將該運算符入棧
6.最終將棧中的元素依次出棧,輸出。
下面截取了遇到等號時的代碼處理。
case ‘(‘: { stack2.push(String.valueOf(c));//如果是( 轉化為字符串壓入字符棧 break; } case ‘)‘: {//遇到右括號了計算,因為(的優先級最高 String stmp = stack2.pop();//如果是),將符號棧棧頂元素取到 while (!stack2.isEmpty() && !stmp.equals("(")) { //當前符號棧裏面還有+ - * / int a = stack1.pop(); //取操做數a,b int b = stack1.pop(); int sresulat = calculate(b, a, stmp); if(sresulat<0) return -1; stack1.push(sresulat);//將結果壓入棧 stmp = stack2.pop();//符號指向下一個計算符號 } break; }
6.測試運行:
進入src文件下,輸入javac -encoding utf-8 Main.java 編譯出相應的class文件,再輸入java Main 進行測試:
7.不足與改進:
在算法的實現過程中,雖然經過了不斷的修改和調整,但目前仍然存在著許多不足:
1.括號的處理,只是處理了幾種特殊情況,並沒有做到括號的隨機並合理,沒有涉及到多重括號的生成和處理,這也是以後改進的一個方向。
2.在出題的過程中,我的方法是將不同數量的運算符的算法之間分離開,造成算法的延展性較差,目前也參考了同學們的代碼,發現自己的代碼如果擴展到10個運算符的情況,會很麻煩,這是接下來需要改進的一點。
3.在最開始進行算法的分析的時候,沒有註意題目的要求,也沒有看到老師推薦的調度場算法,因此,在計算上大費周章,這是今後要避免的一個問題,對於項目要求一定要認真理解。
8.項目總結:
1.在算法的編寫過程中,采用了書中和老師所推薦的“逐步求精”的設法方法,將一個項目分解成幾個不同的小問題,通過編寫不同的方法來逐步解決每個問題,各個方法相互配合,循序漸進,最終達成自己想要的結果。
2.對於算法編寫中出現的許多問題,進行了思考和改進,並且對於項目的延展性有了更深的理解,我的算法延展性不強,這是以後和強化的一點。
9.PSP展示
PSP2.1 |
任務內容 |
計劃共完成需要的時間(min) |
實際完成需要的時間(min) |
Planning |
計劃 |
8 |
10 |
· Estimate |
· 估計這個任務需要多少時間,並規劃大致工作步驟 |
8 |
6 |
Development |
開發 |
450 |
600 |
· Analysis |
· 需求分析 (包括學習新技術) |
20 |
30 |
· Design Spec |
· 生成設計文檔 |
10 |
10 |
· Design Review |
· 設計復審 (和同事審核設計文檔) |
5 |
5 |
· Coding Standard |
· 代碼規範 (為目前的開發制定合適的規範) |
3 |
5 |
· Design |
· 具體設計 |
10 |
20 |
· Coding |
· 具體編碼 |
350 |
500 |
· Code Review |
· 代碼復審 |
10 |
20 |
· Test |
· 測試(自我測試,修改代碼,提交修改) |
15 |
30 |
Reporting |
報告 |
10 |
30 |
· Test Report |
· 測試報告 |
5 |
10 |
· Size Measurement |
· 計算工作量 |
1 |
1 |
· Postmortem & Process Improvement Plan |
· 事後總結, 並提出過程改進計劃 |
5 |
15 |
2016012015+小學四則運算練習軟件項目報告