天天看點

軟體工程第三次作業

要求0:作業位址:  https://edu.cnblogs.com/campus/nenu/2016CS/homework/2266

要求1:https://git.coding.net/tangjh563/f4.git

要求2:

一、程式設計隊友呂鵬鵬及部落格位址: https://www.cnblogs.com/lvpengaaron/ 

二、問題分析:

  一個基于控制台的四則運算系統,要能實作生成并計算含有真,假分數,整數的不超過三個運算符帶有括号的四則運算表達式,并且要能根據使用者所送出的答案生成答題報告,答題報告中主要包括,本次答題的正确,錯誤,和重複表達式出現的情況。生成的表達式和答案要存入檔案中。對生成的表達式有如下要求,不能在過程中産生負數,因為國小生并不會計算負數,以及不能出現除0的情況,因為國小生不會計算除以0。

  從整個需求來看,大緻可以分為三個子產品,生成表達式,表達式計算(包括将表達式和答案寫入檔案),答題報告的生成(包括表達式的查重和根據輸入完成的校驗)。各個子產品之間關系密切,故采用由下至上的不斷疊代的開發模式,先開發最底層的各個樁子產品,在開發每個樁子產品時再采用測試驅動開發的方法,從編寫小的測試用例開始開發樁子產品,當對樁子產品進行整合時,再編寫測試子產品,這樣當開發完成後測試也就完成了。

  所謂相同的運算過程就是,你在做什麼運算我也做什麼運算,你的操作數是啥我的操作數也是啥,出于這個引入一個新的表達式,我将其命名為查重表達式,他的結構是運算在先後面跟着這個運算符的操作數,如(1+2)*3+5的查重表達式就為: +12 * 3 +5 這個表達式的含義就是第一個運算的是加法,加法的操作數是2 和3 第二個運算是乘法,乘法的操作數是前一步計算的結果和3以此類推,而3*(1+2) +5的查重表達式為:+12 * 3+5 與上述完全一緻!這樣在做查重是隻需判斷查重表達式是否一緻或者在查重表達式中第一個字元為‘+’ 或者‘*’的情況下後續的兩個操作數互換位置後是否一緻即可。也就是說上述的查重表達式于+21 * 3+5 也是等價的。

那該如何生成查重表達式,所謂的查重表達式就是描述表達式正在運算的過程,那就在你使用字尾表達式計算時,去生成即可。算法之後給出

三、功能設計:

在四則運算項目.zip中

軟體工程第三次作業

com.wx.appEntrance是作為項目的入口。

com.wx.test 是作為測試功能使用

com.wx.randomTool是作為生成随機的四則運算表達式的,共有四個類組成其中RandExpressionExport(可直接生成表達式)是頂層類,是對RandOperatorNumberExport(可随機生成各類操作數和操作符)進一步封裝,而RandOperatorNumberExport是對RandomExportMachine(可生成數字和字元)的進一步封裝,Ruler則是描述生成表達式的功能.

com.wx.expression是描述表達式的結構

com.wx.calculateTool是用于計算表達式,PostfixExpression用于生成字尾表達式,CalculateRuler描述計算規則,CalculateExpression頂層類對可直接計算表達式,對前面兩個類的封裝。

com.wx.fileIO用于實作檔案操作

com.wx.expressionCnki 用于實作表達式的查重,工具類.

com.wx.report 用于生成答題報告.

四、收獲與不足:

收獲:在這次程式設計過程中,遇到了很多細節性的問題,有一種每次細想一遍就會發現一個小問題的感覺。在解決問題的過程中,又重新複習了資料結構和算法程式設計的相關知識,用到了棧的存儲、中綴表達式與字尾表達式的轉化等。最大的感受就是在上網查閱資料的時候,看了挺多代碼,了解借鑒了别人的程式設計思想,get到了很多用Java程式設計的小技巧。

 不足:有些功能和格式不能完美實作。

五、重要代碼

1、用于描述計算規則的CalculateRuler中的用于化簡表達式的方法simplificationFracrion的代碼如下:

軟體工程第三次作業
 2、用于實作查重的Cnki類中的得到查重表達式的getCnkiExpressionArray方法的代碼如下:
軟體工程第三次作業
3、用于實作查重的Cnki類中的判斷兩個表達式是否重複的代碼如下:
軟體工程第三次作業
4、生成報告代碼:

package com.wx.report;

import com.wx.expression.Expression;
import com.wx.expressionCnki.Cnki;


/**
 * 
 * @author wx
 *
 *該類用作生成答題報告,包括兩部分,第一部分為答案校驗的報告
 *第二部分為查重結果的報告
 */
public class AnswerResport {
    
    private static Cnki cnki = new Cnki();// 用于查重校驗

    /**
     * 
     * @param replyAnswer 使用者的回答
     * @param rightAnswer 正确的答案
     * @return 答案的答題報告
     */
    public static String getAnswerResport(String []replyAnswer,String[] rightAnswer){
        String rightAnswerResport = "Correct: ",rightAnswerList = "正确的題号";//構造正确部分呢過的答題報告
        String wrongAnswerResport = "Wrong",wrongAnswerList = "錯誤的題号";//構造錯誤部分呢過的答題報告
        int rightNumber = 0,wrongNumber = 0;//記錄正确和錯誤的個數
        for(int i = 0;i<replyAnswer.length;i++){//開始校驗使用者的回答
            if(replyAnswer[i].equals(rightAnswer[i])){//答對
                rightNumber++;
                rightAnswerList = rightAnswerList+ (i+1)+",";
            }else{//答錯
                wrongNumber++;
                wrongAnswerList = wrongAnswerList + (i+1) +",";
            }
        }
        rightAnswerResport = rightAnswerResport+rightNumber+"-------"+rightNumber+"道題正确, "+rightAnswerList+"\n";
        wrongAnswerResport = wrongAnswerResport+wrongNumber+"-------"+wrongNumber+"道題正确,"+wrongAnswerList+"\n";
        return rightAnswerResport+wrongAnswerResport;
    }
    
    
    /**
     * 
     * @param expression 要查重的表達式數組
     * @return  查重報告
     */
    public static  String cnkiExpressionAnswerReport(Expression [] expression){
        String cnkiReport = "Repeat:";  //傳回的表達式報告
        String temp = "";
        String tempReport = ""; // 臨時變量,用于出現一次重複情形所産生的資訊.
        int repeatNumber = 0; // 計數出現重複表達式的次數.
        int findRepeatFlag = 0; //标志是否找到重複的表達式
        for(int i = 0;i<expression.length-1;i++){ //雙重循環驗證表達式
            if(expression[i].getCnkiFlag()==1) continue; //若是已經被标記為重複的則跳過繼續下一個表達式
            for(int j = i+1;j<expression.length;j++){
                if(expression[j].getCnkiFlag()==1) continue;//若是已經被标記為重複的則跳過繼續下一個表達式
        //        System.out.print(i+" "+j+"查重結果"+cnki.cnkiExression(expression[i],expression[j]));
                if(cnki.cnkiExression(expression[i],expression[j])){  //出現重複的表達式
                    expression[i].setCnkiFlag(1); //設定重複标志
                    expression[j].setCnkiFlag(1); //設定重複标志
                    findRepeatFlag = 1;
                    temp  = temp + (j+1) +","+expression[j].getExpression()+" ";
                }
                if(findRepeatFlag == 1) {//找到重複的
                    repeatNumber++;
                    findRepeatFlag = 0;//重置标志
                    tempReport  = "("+ (repeatNumber)+")"+ (i+1)+", "+expression[i].getExpression() +" Repeat " +tempReport +temp;//構造單次重複報告
                    temp = "";
                }
            }
        }
        cnkiReport  = cnkiReport+repeatNumber;
        if(repeatNumber!=0){
            cnkiReport  = cnkiReport+"\n"+"RepeatDetail:\n"+tempReport;
        }
        return cnkiReport;
        
    }
}      

  

PSP

PSP2.1 Personal Software Process Stages Estimated time(min) actual time(min)
Planning 計劃 30 25
· Estimate 估計這個任務需要多少時間 740 800
Development 開發 80 90
· Analysis 需求分析 (包括學習新技術) 10
· Design Spec 生成設計文檔 7
· Design Review 設計複審 6 5
· Coding Standard 代碼規範 4
· Design 具體設計 300 400
· Coding 具體編碼 350
· Code Review 代碼複審 15
· Test 測試(自我測試,修改代碼,送出修改)
Reporting 報告 20
· 測試報告
計算工作量
并提出過程改進計劃

總結:   在做作業的時候,體會到了邏輯清晰是有多重要,不管程式設計能力怎麼樣,首先看見一道題目時不要急着就去做,想想如何做怎麼做才是最重要的,如果邏輯清晰知道需要建幾個類,每個類包含什麼,每個類之間的關系是什麼,就算個别方法不會寫,大體的模子也能畫出來,最後要就個别函數即可。下次我做作業的時候應該會多花時間在邏輯分析,流程圖上。