2019-2020-4 《Java 程序設計》結對項目階段總結---《四則運算——整數》
1、需求分析
實現一個命令行程序java
要求:git
- 自動生成小學四則運算題目(加,減,乘,除);
- 支持整數;
- 支持多運算符(例如生成包含n個運算符的題目);
- 支持真分數(後續實現);
- 統計正確率。
擴展需求編程
- 文件: (1) 處理生成題目並輸出到文件; (2) 完成題目後從文件讀入並判斷。
- 多語言支持:簡體中文,繁體中文,English;
- 生成題目去重。
2、設計思路以及代碼解釋
剛拿到結對項目數組
剛拿到結對項目時,感受不是很難,是由於沒有考慮到括號、運算優先級以及多個數字運算的問題,因此只是簡單設計了一個兩個數字簡單的四則運算,具體程序以下:dom
//生成隨機整數的運算學習
public class Zheng { int a=0,b=0,c=0; int result=0,g=0; String s=null; public void Zheng(){ a = (int)(Math.random()*100);//生成0-99的隨機數 b = (int)(Math.random()*100); c = (int)(Math.random()*4);//生成0-3的隨機數,用來隨機產生運算符 if(c==0){ System.out.println(a+"+"+b+"="); result = a + b; } if(c==1){ System.out.println(a+"-"+b+"="); result = a - b; } if(c==2){ System.out.println(a+"*"+b+"="); result = a * b; } if(c==3){ if(b==0){ while(b==0) b=(int)(Math.random()*10);//防止分母爲0 } else{ System.out.println(a+"/"+b+"="); int smaller = a > b ? b : a;//將a與b中的最小值賦給變量 for (int i = 1; i <= smaller; i++) { if (a % i == 0 && b % i == 0) { g = i; }//求a與b的最大公因子 } a = a/g; b = b/g; s = a+"/"+b; } } } }
//實現四則運算spa
import java.util.*; public class YunSuan { public static void main (String args[]){ int x,z=0; Zheng zheng = new Zheng(); System.out.print("請輸入要生成的題目數:"); Scanner reader = new Scanner(System.in); int n = reader.nextInt(); Random random = new Random(); for(int i=1;i<n+1;i++){ for(;;){ System.out.println("題目"+i+":"); zheng.Zheng(); System.out.print("請輸入結果:"); if(zheng.c==3){ Scanner sc=new Scanner(System.in); String s =new String(); s =sc.nextLine(); if(s.equals(zheng.s)){ z++; System.out.println("此題正確"); } else System.out.println("此題錯誤,正確答案爲:"+zheng.s); } else{ x =reader.nextInt(); if(x==zheng.result){ z++; System.out.println("此題正確"); } else System.out.println("此題錯誤,正確答案爲:"+zheng.result); } break; } } int o =(int)(((double)z/(double)n)*100);//計算正確率 System.out.print("完成"+n+"道題,正確數目爲:"+z+",正確率爲:"); System.out.printf("%d",o); System.out.println("%"); } }
簡單四則運算碼雲連接:連接命令行
考慮到多種因素後設計
當發現須要考慮括號、運算優先級以及多個數字計算的因素時,發現事情沒那麼簡單,而後瘋狂腦闊疼.........,在看到棧以及中綴轉後綴等問題後,陷入了沉思,在經過長時間的學習和理解後才知道如何解決括號與計算問題,以前沒有這些知識前,根本無從下手,經過最終地艱苦奮鬥仍是設計出代碼,可是仍是有些問題,代碼以下:code
//生成隨機數
import java.util.*; public class RandomNum { int RandomNum(int x){ int num =(int)(Math.random()*x); return num; } } //生成隨機運算符 import java.util.*; public class RandomChar { char RandomChar(){ int num = (int)(Math.random()*4); switch (num){ case 0:return'+'; case 1:return'-'; case 2:return'*'; case 3:return'÷'; default:return 0; } } }
//生成中綴表達式以及產生題目
import java.util.*; public class Produce { void Produce(int n){ RandomNum num = new RandomNum(); RandomChar c = new RandomChar(); Scanner reader = new Scanner(System.in); String s = ""; String d = ""; String g = ""; String out = "";//最終的中綴表達式 String end = "";//轉化後的後綴表達式 int count = 0;//記錄作對的題目個數 for(int i=1;i<n+1;i++){ System.out.println("題目"+i+":"); int a = (int)(Math.random()*5+1); int amount = num.RandomNum(a)+1;//記錄隨機產生運算符的個數 for(int j=0;j<amount;j++){ s = s+c.RandomChar()+" "; } String str[] = s.split(" ");//將字符串轉化成字符串數組 for(int z=0;z<str.length;z++){ d = d+num.RandomNum(50)+str[z]; } d = d + num.RandomNum(50); switch((num.RandomNum(2))){ case 0: System.out.println(d+" = ");//輸出不帶括號的中綴表達式 break; case 1: for(int k=0;k<str.length;k++){ g = num.RandomNum(50)+ str[num.RandomNum(str.length-1)] + "(" + num.RandomNum(50) + str[num.RandomNum(str.length-1)] + num.RandomNum(50) + ")" + str[k]; }//在中綴表達式中加入括號 g = g + num.RandomNum(50); System.out.println(g+" = ");//輸出不帶括號的中綴表達式 break; } out = g; out = d; int p = 0;//初始化最終獲得的答案 infixToSuffix in = new infixToSuffix(); end = in.infixToSuffix(out);//將中綴表達式轉化爲後綴表達式 suffixToArithmetic ex = new suffixToArithmetic(); p = (int) ex.suffixToArithmetic(end);//計算後綴表達式的結果 System.out.print("請輸入結果:"); int x = reader.nextInt(); if(x==p){ System.out.println("結果正確!"); count++; } else{ System.out.println("結果錯誤,正確結果是:"+p); } s=""; g=""; d=""; } int result = (int)(((double)count/(double)n)*100);//計算正確率 System.out.println("總共答題"+n+"道,正確率爲:"+result+"%"); } }
//將中綴表達式轉化爲後綴表達式
import java.util.*; public class infixToSuffix { public static String infixToSuffix(String infix) { Stack<Character> stack = new Stack<Character>(); String suffix = ""; int length = infix.length(); for (int i = 0; i < length; i++) { Character temp; char c = infix.charAt(i); switch (c) { // 忽略空格 case ' ': break; // 碰到'(',push到棧 case '(': stack.push(c); break; // 碰到'+''-',將棧中全部運算符彈出,送到輸出隊列中 case '+': case '-': while (stack.size() != 0) { temp = stack.pop(); if (temp == '(') { stack.push('('); break; } suffix += " " + temp; } stack.push(c); suffix += " "; break; // 碰到'*''/',將棧中全部乘除運算符彈出,送到輸出隊列中 case '*': case '/': while (stack.size() != 0) { temp = stack.pop(); if (temp == '(' || temp == '+' || temp == '-') { stack.push(temp); break; } else { suffix += " " + temp; } } stack.push(c); suffix += " "; break; // 碰到右括號,將靠近棧頂的第一個左括號上面的運算符所有依次彈出,送至輸出隊列後,再丟棄左括號 case ')': while (stack.size() != 0) { temp = stack.pop(); if (temp == '(') break; else suffix += " " + temp; } // suffix += " "; break; //若是是數字,直接送至輸出序列 default: suffix += c; } } //若是棧不爲空,把剩餘的運算符依次彈出,送至輸出序列。 while (stack.size() != 0) { suffix += " " + stack.pop(); } return suffix; } }
//計算後綴表達式的值
import java.util.*; public class suffixToArithmetic{ int suffixToArithmetic(String h) { Stack<Integer>stack = new Stack<Integer>(); String b[] = h.split(" ");//將字符串轉化爲字符串數組 for(int i=0;i<b.length;i++){ String c = b[i]; if((c.equals("+")||c.equals("-"))||(c.equals("*")||c.equals("÷"))){ int y = stack.pop(); int x = stack.pop(); Caculate z = new Caculate(); stack.push(z.Caculate(x,y,c));//將運算結果從新壓入棧 }//是運算符,彈出運算數,計算結果 else{ stack.push(Integer.valueOf(c)); } } return stack.pop();//彈出棧頂元素就是運算最終結果 } }
//斷定運算符並進行運算
class Caculate{ int Caculate(int x,int y,String c) { if (c.equals("+")) return x + y; if (c.equals("-")) return x - y; if (c.equals("*")) return x * y; if (c.equals("/")){ if(x<=y||x==0) return 1; else return x / y; } return 0; } }
完善後四則運算碼雲連接:連接
3、總結分析與運行截圖
結對項目總結與分析
開始覺得項目應該很快就能完成,發現缺乏好多知識後就很難完成這個項目,不得不將新知識學習後再進行編程,在編程中遇到往中綴表達式加入括號的問題,以及除法計算的問題,遇到左右括號數量不等的狀況,遇到括號只括住一個數字或者一個運算符的問題,遇到碰見除法沒法輸出的問題,遇到沒法計算出結果的問題,這些問題都在最後與同伴的討論中獲得部分解決,仍是有些問題沒有獲得解決。程序的UML圖將在完善程序後的博客中體現。 除法計算問題的截圖:
運行截圖體現
簡單四則運算的運行截圖:
部分完善後的運行截圖:
4、結對同伴的評價
結對同伴陳敬勇在完成這次項目中的表現很是出色,咱們在遇到問題後都能認真討論得出答案,避免了一我的完成任務時的思惟定式的問題,咱們相互鼓勵支持,相信在下來的完善代碼問題的過程當中,咱們會作的更好。