軟件工程 做業三

軟件工程 做業三


1.要求地址


2.PSP表格

PSP2.1 我的開發流程 預估耗費時間(分鐘) 實際耗費時間(分鐘)
Planning 計劃 5 3
· Estimate 明確需求和其餘相關因素,估計每一個階段的時間成本 5 3
Development 開發 274 308
· Analysis 需求分析 (包括學習新技術) 60 60
· Design Spec 生成設計文檔 5 2
· Design Review 設計複審 4 2
· Coding Standard 代碼規範 5 5
· Design 具體設計 10 20
· Coding 具體編碼 120 180
· Code Review 代碼複審 10 9
· Test 測試(自我測試,修改代碼,提交修改) 60 30
Reporting 報告 40 65
· 測試報告 30 60
· 計算工做量 5 2
· 並提出過程改進計劃 3 3

3.解題思路描述

此次的項目是創建在上一次做業的項目的基礎上,在功能上,主要有兩個新增的地方:html

  • 詞組統計:能統計文件夾中指定長度的詞組的詞頻
  • 自定義輸出:能輸出用戶指定的前n多的單詞與其數量

而後在設計上則是新增了GUI界面java

詞組統計的話,是使用了多重循環,分層進行判斷,在存儲方面也是使用了Map進行存儲。git

自定義輸出的解題思路:戳這裏戳這裏戳這裏web

GUI界面使用了netbeans以及web來實現。編程

我對於GUI界面是使用了netBeans來實現,使用了文本框控件,菜單控件等來實現處理文件以及字符處理,經過給不一樣按鈕添加相應事件,以此來實現不一樣的功能。app

web界面的解題解題思路:戳這裏戳這裏戳這裏jsp


4.設計實現過程

1、相關類設計

  • WordDeal類,用於存放統計字符數、行數、單詞數、詞頻等方法。
  • FileDeal類做爲文件處理類,用於讀取文件內容以及寫入文件。
  • Test類,用於進行單元測試。​

2、相關函數設計

  1. FIleDeal類中的方法
    • FileToString方法實現讀取一個文件,而且返回文件內容,保存在一個字符串中。
    • WriteToFile方法實現把統計結果寫入指定文件。
  2. WordDeal類中的方法
    • getCharCount()方法實現統計字符數。
    • getLineCount()方法實現計算行數。
    • getWordCount()方法實現計算單詞數。
    • getWordFreq()方法實現統計每個單詞的詞頻。
    • sortMap()方法實現對Map中的數據進行排序,先按詞頻數後按字典順序。
    • ListToArray()方法實現取出詞頻數前十的數據。
    • getWordGroupFreq(int num)方法用於統計長度爲num的詞組
  3. ScDeal類中的方法
    • 初始化函數scDeal()
    • 判斷輸入函數judge()
    • ideal()是-i的處理函數
    • mdeal()是-m的處理函數
    • ndeal()是-n的處理函數
    • odeal()輸出到文件函數
    •  judge()判斷各自輸入而後調用不一樣的處理函數

3、GUI界面設計

  1. netBeans版本:
    • wGUI包下的Main類,使用netBeans設計其相關界面佈局等。
  2. Web版本:
    • Main.jsp頁面,用於基本界面的設計實現
    • show.jsp頁面,用於表單提交處理界面的實現

5.代碼說明

1.getWordGroupFreq(int num)函數

這個函數實現了統計指定長度的詞組的詞頻信息,經過傳入詞組長度,而後遍歷整個文件內容,先判斷單詞,再進行詞組的判斷。最後的存儲仍是使用Map來進行存儲,以便於統計輸出。ide

public Map getWordGroupFreq(int num) // 統計詞組詞頻(單詞:以4個英文字母開頭,跟上字母數字符號,單詞以分隔符分割,不區分大小寫。)
{
    wordGroupFreq = new HashMap<String, Integer>();
    String t = text;

    String[] spWord = t.split("\\s+"); // 對字符串進行分詞操做
    for (int i = 0; i < spWord.length - num + 1; i++) {
        String wordG = "";
        int isWG = 1;
        for (int j = i; j < i + num; j++) {
            if (spWord[j].length() < 4) { // 判斷是不是單詞,若不是,則直接不用考慮這個詞組
                isWG = 0;
                break;
            } else {

                int flag = 1; // 判斷字符串的前四位是不是英文字母
                char c;

                for (int k = 0; k < 4; k++) {
                    c = spWord[j].charAt(k);

                    if (!(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z')) {
                        flag = 0;
                    }
                }
                if (flag == 0) {
                    isWG = 0;
                    break;
                } else {
                    wordG = wordG + spWord[j] + " ";
                }
            }
        }

        if (isWG == 1 && wordG.trim().length() != 0) {
            if (wordGroupFreq.get(wordG.trim()) == null) { // 判斷以前Map中是否出現過該詞組
                wordGroupFreq.put(wordG.trim(), 1);
            } else {
                wordGroupFreq.put(wordG.trim(), wordGroupFreq.get(wordG.trim()) + 1);
            }

        }

    }

    return wordGroupFreq;
}

2.GUI界面主要函數

  1. 打開文件函數

    該函數用於實現菜單控件中打開文件的功能實現。經過選取文件,將文件內容顯示到相應的地方。佈局

    private void openFileActionPerformed(java.awt.event.ActionEvent evt) {                                         
            f = new Frame("my window");// 建立窗體對象
            f.setBounds(300, 100, 650, 600);// 設置窗體位置和大小
            open = new FileDialog(f, "打開", FileDialog.LOAD);
    
            open.setVisible(true);//顯示打開文件對話框
    
            String dirpath = open.getDirectory();//獲取打開文件路徑並保存到字符串中。
            String fileName = open.getFile();//獲取打開文件名稱並保存到字符串中
    
            if (dirpath == null || fileName == null)//判斷路徑和文件是否爲空
            {
                return;
            } else {
                text.setText(null);//文件不爲空,清空原來文件內容。
            }
            File file = new File(dirpath, fileName);//建立新的路徑和名稱
    
            try {
                //BufferedReader bufr = new BufferedReader(new FileReader(file));//嘗試從文件中讀東西
                BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream(file), "gb2312"));
                String line = null;//變量字符串初始化爲空
                while ((line = bufr.readLine()) != null) {
                    text.append(line + "\r\n");//顯示每一行內容
                }
                bufr.close();//關閉文件
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
  2. 保存文件

    該函數用於將結果框中的內容保存爲文件。

    private void saveFileActionPerformed(java.awt.event.ActionEvent evt) {           
            save = new FileDialog(f, "保存", FileDialog.SAVE);
    
            save.setVisible(true);//顯示保存文件對話框
            String dirpath = save.getDirectory();//獲取保存文件路徑並保存到字符串中。
            String fileName = save.getFile();////獲取打保存文件名稱並保存到字符串中
    
            if (dirpath == null || fileName == null)//判斷路徑和文件是否爲空
            {
                return;//空操做
            } else {
                file = new File(dirpath, fileName);//文件不爲空,新建一個路徑和名稱
            }
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter(file));
    
                String text = result.getText();//獲取文本內容
                bw.write(text);//將獲取文本內容寫入到字符輸出流
    
                bw.close();//關閉文件
            } catch (IOException e1) {
                //拋出IO異常
                e1.printStackTrace();
            }
        }
  3. 功能函數的調用

    這一類的方法是根據點擊的不一樣按鈕,對應實現不一樣的方法,並將結果進行展現。

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
            // TODO add your handling code here:
            String t = text.getText();
            WordDeal wd = new WordDeal(t);
            // 調用類中的方法獲取相應的數值
            int charNum = wd.getCharCount();
            int wordCount = wd.getWordCount();
            int ValidLine = wd.getLineCount();
            Map<String, Integer> wordFreq = wd.getWordFreq();
    
            List sortMap = wd.sortMap(wordFreq);
    
            String[] wFreq = wd.ListToArray(sortMap);
    
            String w = "字符總數:" + charNum + "\r\n" + "單詞總數" + wordCount + "\r\n" + "有效行數" + ValidLine + "\r\n詞頻統計:\r\n";
            for (int i = 0; i < wFreq.length; i++) {
                w = w + wFreq[i] + "\r\n";
            }
            result.setText(w);   //寫入到相應的控件之中
    
    
        }

6.迴歸測試

  1. 對原有函數的迴歸測試

    package junitTest;
    
    import static org.junit.Assert.*;
    import java.io.IOException;
    import java.util.*;
    import org.junit.Before;
    import org.junit.Test;
    import wCount.*;
    
    public class WordDealTest {
    
     @Before
     public void setUp() throws Exception {
    
     }
    
     @Test
     public void testGetCharCount() throws IOException {//統計字符數量測試
         FileDeal fd = new FileDeal();
         String text1 = fd.FileToString("text/text1.txt");   
         String text2 = fd.FileToString("text/text2.txt");   
         String text3 = fd.FileToString("text/text3.txt");
         String text4 = fd.FileToString("text/text4.txt");
    
    
         WordDeal wd1 = new WordDeal(text1);
         WordDeal wd2 = new WordDeal(text2);
         WordDeal wd3 = new WordDeal(text3);
         WordDeal wd4 = new WordDeal(text4);
    
         int cn1 = wd1.getCharCount();
         int cn2 = wd2.getCharCount();
         int cn3 = wd3.getCharCount();
         int cn4 = wd4.getCharCount();
    
         assertEquals(0, cn1);
         assertEquals(0, cn2);
         assertEquals(80, cn3);
         assertEquals(73, cn4);
    
     }
    
     @Test
     public void testGetWordCount() throws IOException {//統計單詞數量測試
         FileDeal fd = new FileDeal();
         String text1 = fd.FileToString("text/text1.txt");
         String text2 = fd.FileToString("text/text4.txt");
    
         WordDeal wd1 = new WordDeal(text1);
         WordDeal wd2 = new WordDeal(text2);
    
         int wn1 = wd1.getWordCount();
         int wn2 = wd2.getWordCount();
    
         assertEquals(0, wn1);
         assertEquals(3, wn2);
     }
    
     @Test
     public void testGetWordFreq() throws IOException {//統計詞頻測試
         Map<String,Integer> ans1 = new HashMap<String,Integer>();
         Map<String,Integer> ans2 = new HashMap<String,Integer>();
    
         ans2.put("coverage", 1);
         ans2.put("yizhishuijiao", 2);
    
         FileDeal fd = new FileDeal();
         String text1 = fd.FileToString("text/text1.txt");
         String text2 = fd.FileToString("text/text4.txt");
    
         WordDeal wd1 = new WordDeal(text1);
         WordDeal wd2 = new WordDeal(text2);
    
         Map<String,Integer> wf1 = wd1.getWordFreq();
         Map<String,Integer> wf2 = wd2.getWordFreq();
    
         assertEquals(ans1, wf1);
         assertEquals(ans2, wf2);
     }
    
     @Test
     public void testSortMap() throws IOException {//詞頻排序測試
    
    
         FileDeal fd = new FileDeal();
         String text1 = fd.FileToString("text/text1.txt");
         String text2 = fd.FileToString("text/text4.txt");
    
         WordDeal wd1 = new WordDeal(text1);
         WordDeal wd2 = new WordDeal(text2);
    
         Map<String,Integer> wf1 = wd1.getWordFreq();
         Map<String,Integer> wf2 = wd2.getWordFreq();
    
         List lis1 = wd1.sortMap(wf1);
         List lis2 = wd2.sortMap(wf2);
    
         //assertEquals(ans1, wf1);
         //assertEquals(ans2, wf2);
     }
    
     @Test
     public void testGetLineCount() throws IOException {//統計有效行數測試
         FileDeal fd = new FileDeal();
         String text1 = fd.FileToString("text/text1.txt");
         String text2 = fd.FileToString("text/text4.txt");
    
         WordDeal wd1 = new WordDeal(text1);
         WordDeal wd2 = new WordDeal(text2);
    
         int wn1 = wd1.getLineCount();
         int wn2 = wd2.getLineCount();
    
         assertEquals(0, wn1);
         assertEquals(4, wn2);
     }
    
     @Test
     public void testListToArray() throws IOException {
    
    
         FileDeal fd = new FileDeal();
         String text1 = fd.FileToString("text/text1.txt");
         String text2 = fd.FileToString("text/text4.txt");
         String text3 = fd.FileToString("text/text5.txt");
    
         WordDeal wd1 = new WordDeal(text1);
         WordDeal wd2 = new WordDeal(text2);
         WordDeal wd3 = new WordDeal(text3);
    
         Map<String,Integer> wf1 = wd1.getWordFreq();
         Map<String,Integer> wf2 = wd2.getWordFreq();
         Map<String,Integer> wf3 = wd3.getWordFreq();
    
         List lis1 = wd1.sortMap(wf1);
         List lis2 = wd2.sortMap(wf2);
         List lis3 = wd3.sortMap(wf3);
    
         String[] s1 = wd1.ListToArray(lis1);
         String[] s2 = wd2.ListToArray(lis2);
         String[] s3 = wd3.ListToArray(lis3);
     }
    
    }

    測試結果:

  2. 對新增函數的測試

    測試用例:

    測試代碼:

    @Test
     public void testGetWordGroupFreq() throws IOException {//統計詞組測試
    
         FileDeal fd = new FileDeal();
         String text6 = fd.FileToString("text/text6.txt");
         WordDeal wd6 = new WordDeal(text6);
         Map<String,Integer> wf6 = wd6.getWordGroupFreq(3);  
     }

    測試結果:


7.單元測試

  1. 對命令行版本項目的單元測試






  2. 對web版本項目的單元測試







  1. 對netBeans版本項目的單元測試








    ------

8.效能測試

  1. 對命令行版本項目的效能測試

  2. 對web版本項目的效能測試



  1. 對netBeans版本項目的效能測試



9.結對心得

此次的結對編程是針對一個項目進行的改進,由於此次的要求,命令行輸入和GUI界面的實現是兩個相對獨立的版本,因此通過討論之後,咱們的分工基本仍是由我寫完新增函數之後,由每一個人來實現一個版本,相對來講除了在調用函數方面,其餘部分仍是比較獨立的,因此其實並無不少結對的感受,可是在最開始討論的時候,每一個人都尚未很清晰的認識這個過程,致使對這個項目各有各的見解,而後討論的效率仍是比較低,花了很長時間才獲得的統一。因此此次編程並無不少的感覺到1+1>2的效果

相關文章
相關標籤/搜索