Java開發,基於控制台的四則運算表達式生成和批改,能夠實現分數計算和真分數結果顯示。GitHub:https://github.com/Umbrellazc/JavaCalculation ...
一、題目要求
FileCal.java → 題庫文件寫入操作
GenerateCal → 根據用戶參數生成四則遠算,並組合成題庫
com.cal.main包:
GetExercise → 生成四則運算程式入口,讀取參數(-n,-r,-o)
VaildateExe → 檢查四則運算結果程式入口,讀取參數(-e)
com.cal.mold包:
FractionCal → 分數加減乘除計算結果
FractionStack → 分數分裝
MainParameter → 程式入口參數分裝
OutFileCal → 題庫分裝
RPNCalculator → 四則遠算轉尾碼表達式,即進行逆波蘭操作
trashcan包:
暫時沒有用處或已經被替換的類
五、關鍵代碼說明
package com.cal.mold; import java.util.HashMap; import java.util.List; import java.util.Stack; /** * 逆波蘭表達式轉換 * 計算四則運算結果 */ public class RPNCalculator { //運算符優先順序 private static HashMap<String,Integer> opLs; private FractionCal fc = new FractionCal(); private String src; public RPNCalculator(String src) { this.src = src; if(opLs==null) { opLs = new HashMap<String,Integer>(6); opLs.put("+",0); opLs.put("-",0); opLs.put("*",1); opLs.put("/",1); opLs.put("%",1); opLs.put(")",2); } } //將中綴表達式轉化為尾碼表達式 public String toRpn() { String[] tmp = split(src); // 尾碼棧 Stack<String> rpn = new Stack<String>(); // 臨時棧 Stack<String> tmpSta = new Stack<String>(); for (String str : tmp) { if (isNum(str)) { //是操作數,直接壓入結果棧 rpn.push('('+str+')'); }else{ //是操作符號 if(tmpSta.isEmpty()) {//還沒有符號 tmpSta.push(str); }else{ //判讀當前符號和臨時棧棧頂符號的優先順序 if(isHigh(tmpSta.peek(),str)) { if(!str.equals(")")) { do{ //1在臨時棧中找出小於當前優先順序的操作符 //2壓入當前讀入操作符 rpn.push(tmpSta.peek()); tmpSta.pop(); }while(!tmpSta.isEmpty()&&(isHigh(tmpSta.peek(),str))); tmpSta.push(str); }else{ //是)依次彈出臨時棧的數據,直到(為止 while(!tmpSta.isEmpty()&&!tmpSta.peek().equals("(")) { rpn.push(tmpSta.pop()); } if((!tmpSta.empty())&&(tmpSta.peek().equals("("))) {//彈出( tmpSta.pop(); } } }else if(!isHigh(tmpSta.peek(),str)){ tmpSta.push(str); } } } } while(!tmpSta.empty()) {//把棧中剩餘的操作符依次彈出 rpn.push(tmpSta.pop()); } StringBuilder st = new StringBuilder(); for (String str : rpn) { st.append(str); } rpn.clear(); return st.toString(); } //分割(56+4)3*6+2=>(,56,+,4, private String[] split(String src) { StringBuilder sb = new StringBuilder(src.length()); for(char ch:src.toCharArray()) { if(ch=='+'||ch=='-'||ch=='*'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='%') { sb.append(","); sb.append(ch); sb.append(","); }else{ sb.append(ch); } } String string = sb.toString().replaceAll(",{2,}", ","); return string.split(","); } //比較操作符的優先順序 private boolean isHigh(String pop, String str) { if(str.equals(")")) return true; if(opLs.get(pop)==null||opLs.get(str)==null) return false; return opLs.get(pop)>=opLs.get(str); } //是否是數字 public boolean isNum(String str) { for (char ch : str.toCharArray()) { if(ch=='+'||ch=='-'||ch=='*'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='%') return false; } return true; } //得到結果 public FractionStack calculate() { String rpn = toRpn(); Stack<FractionStack> res = new Stack<FractionStack>(); StringBuilder sb = new StringBuilder(); for(char ch:rpn.toCharArray()) { if(ch=='(') { continue; }else if(ch>='0'&&ch<='9'||ch=='.'){ sb.append(ch); }else if(ch==')') { FractionStack fs = new FractionStack(); fs.setNumerator(Integer.parseInt(sb.toString())); fs.setDenominator(1); res.push(fs); sb = new StringBuilder(); }else{ if(!res.empty()) { FractionStack rear = res.pop(); FractionStack front = res.pop(); System.out.println("rear:"+rear.getRes()); System.out.println("front:"+front.getRes()); switch (ch) { case '+': res.push(fc.fracAdd(front, rear)); break; case '-': res.push(fc.fracSub(front, rear)); break; case '*': res.push(fc.fracMul(front, rear)); break; case '/': res.push(fc.fractDiv(front, rear)); break; } } } } FractionStack result = res.pop(); res.clear(); return result; } /* *計算生成題目的結果 */ public List<OutFileCal> GetExerciseRes(List<OutFileCal> caList){ for(int i=0;i<caList.size();i++){ String exe = caList.get(i).getCalExe(); RPNCalculator analyer = new RPNCalculator(exe); String res = analyer.calculate().getRealRes(); caList.get(i).setCalRes(res); } return caList; } }View Code
上面為逆波蘭表達式轉換過程和計算四則運算結果
package com.cal.mold; public class FractionCal { //private FractionStack fs = new FractionStack(); //分數加法 public FractionStack fracAdd(FractionStack f1,FractionStack f2){ FractionStack fs = new FractionStack(); int first_numerator = f1.getNumerator();int first_denominator = f1.getDenominator(); int second_numrator = f2.getNumerator();int second_denominator = f2.getDenominator(); int denominator; int numerator; if(first_denominator==second_denominator) //分母相同時加分子 { denominator=first_denominator; numerator=first_numerator+second_numrator; } else //否則同分比較分子 { denominator=first_denominator*second_denominator; numerator=first_numerator*second_denominator+first_denominator*second_numrator; } int gcd = gcd(numerator,denominator); denominator = denominator / gcd; numerator = numerator / gcd; fs.setNumerator(numerator); fs.setDenominator(denominator); System.out.println("加法輸出的結果是"+fs.getRes()); return fs; } //分數減法 public FractionStack fracSub(FractionStack f1,FractionStack f2){ FractionStack fs = new FractionStack(); int first_numerator = f1.getNumerator();int first_denominator = f1.getDenominator(); int second_numerator = f2.getNumerator();int second_denominator = f2.getDenominator(); int denominator; int numerator; if(first_denominator==second_denominator) //分母相同時加分子 { denominator=first_denominator; numerator=first_numerator-second_numerator; } else //否則同分比較分子 { denominator=first_denominator*second_denominator; numerator=first_numerator*second_denominator-first_denominator*second_numerator; } int gcd = gcd(numerator,denominator); denominator = denominator / gcd; numerator = numerator / gcd; fs.setNumerator(numerator); fs.setDenominator(denominator); System.out.println("減法輸出的結果是"+fs.getRes()); return fs; } //分數乘法 public FractionStack fracMul(FractionStack f1,FractionStack f2){ FractionStack fs = new FractionStack(); int first_numerator = f1.getNumerator();int first_denominator = f1.getDenominator(); int second_numerator = f2.getNumerator();int second_denominator = f2.getDenominator(); int denominator; int numerator; denominator=first_denominator*second_denominator; numerator=first_numerator*second_numerator; int gcd = gcd(numerator,denominator); denominator = denominator / gcd; numerator = numerator / gcd; fs.setNumerator(numerator); fs.setDenominator(denominator); System.out.println("乘法輸出的結果是"+fs.getRes()); return fs; } //分數除法 public FractionStack fractDiv(FractionStack f1,FractionStack f2){ FractionStack fs = new FractionStack(); int first_numerator = f1.getNumerator();int first_denominator = f1.getDenominator(); int second_numerator = f2.getNumerator();int second_denominator = f2.getDenominator(); int denominator; int numerator; numerator = first_numerator*second_denominator; denominator = first_denominator*second_numerator; int gcd = gcd(numerator,denominator); denominator = denominator / gcd; numerator = numerator / gcd; fs.setNumerator(numerator); fs.setDenominator(denominator); System.out.println("除法輸出的結果是"+fs.getRes()); return fs; } //獲取最大公約數 static int gcd(int x,int y){ int r; while( y!= 0) { r = x%y; x = y; y = r; } return x; } }View Code
上面為分數計算器
六、運行測試
1.生成題庫
2.題目結果驗證
七、PSD統計
PSP2.1 | Personal Software Process Stages | Time Senior Student | Time | |
Planning | 計劃 | 12 | 12 | |
· Estimate | 估計這個任務需要多少時間 | 12 | 12 | |
Development | 開發 | 6 | 6 | |
· Analysis | 需求分析 (包括學習新技術) | 6 | 10 | |
· Design Spec | 生成設計文檔 | 5 | 6 | |
· Design Review | 設計覆審 | 4 | 6 | |
· Coding Standard | 代碼規範 | 3 | 3 | |
· Design | 具體設計 | 10 | 12 | |
· Coding | 具體編碼 | 36 | 21 | |
· Code Review | 代碼覆審 | 7 | 9 | |
· Test | 測試(自我測試,修改代碼,提交修改) | 13 | 21 | |
Reporting | 報告 | 9 | 6 | |
測試報告 | 3 | 2 | ||
計算工作量 | 2 | 1 | ||
並提出過程改進計劃 | 3 | 3 |
八、作業小結
1.題目生成難度還有待開發
2.四則運算題目出題關鍵代碼部分還可以改進,括弧增減更加靈活
3.查重仍待開發
4.文件流讀寫代碼冗餘程度較大
GitHub:https://github.com/Umbrellazc/JavaCalculation