201671010412 郭佳 實驗二 軟件工程我的項目

做業要求:《實驗二 軟件工程我的項目》

本項目Github的倉庫主頁

1. 需求分析

本次實驗要求使用JAVA編程語言,獨立完成一個英文文本詞頻統計的軟件開發。
該程序要求實現:html

  • 要求可以讀入任意英文文本文件,該文件中英文詞數大於等於一個;
  • 要可以容納英文原版《哈利波特》10萬詞以上的文章;
  • 要有指定單詞的詞頻統計功能,即用戶可輸入從該文本中想要查找詞頻的一個或任意多個英文單詞,運行程序的統計功能可顯示對應單詞在文本中出現的次數和柱狀圖;
  • 高頻單詞統計功能,即用戶共鍵盤輸入高頻詞輸出個數k,運行程序統計功能,可按文本中詞頻數降序顯示前k個單詞的詞頻及單詞;
  • 統計該文本全部單詞數量及詞頻數,並能將單詞及詞頻數按字典順序輸出到文件result.txt

2. 功能設計

根據需求分析中提到的內容,本程序中設計如下幾個功能:java

  • 統計文件中全部單詞及其詞頻數,且輸出到指定文件;
  • 統計指定單詞在文件中出現的次數;
  • 輸出前K個高頻詞的個數及其柱狀圖;

程序流程圖:
程序流程圖git

3. 設計實現

本程序包含四個類,包括一個主函數Main.java和三個功能類,分別是Count1.java,Count1.java,Count1.java主程序主要是用來控制程序的整個流程,用戶輸入不一樣的功能選項,來調用這三個功能。三個類的功能分別是:github

  • Count1.java:該類是用來實現對指定文件中全部單詞及其詞頻進行統計功能的,統計完成後並將統計結果輸出到指定文件中。
  • Count2.java:該類是用來實現用戶從鍵盤輸入任意一個單詞,查詢並統計該單詞在文件中出現的次數功能的,若查詢的該單詞不存在則顯示提示信息。
  • Count3.java:該類是用來實現統計用戶指定任意個數的高頻詞頻及其柱狀圖功能的。

4. 測試運行

  • 本程序主界面顯示以下:

  • 功能選項1測試:

    選擇選項1,顯示文件中全部單詞個數及其詞頻統計結果,並將結果輸出到指定文件中。

    編程

  • 功能選項2測試:

    用戶任意輸入想要在文件中查詢的單詞,查詢並顯示結果,若該文件中不存在該單詞則提示錯誤信息。
    小程序

  • 功能選項3測試:

    用戶輸入想要查詢統計的任意個數K個高頻單詞,查詢成功則顯示單詞詞頻及其柱狀圖
    數組

    若輸入查詢個數爲不在有效範圍內(負數或者大於文中單詞類型個數),則提示相應的錯誤信息。
    框架

  • 功能選項4:

    退出程序,不在輸出菜單。
    編程語言

5. 代碼片斷

  • 讀取指定文件
String filecontent = "";//用來存放讀取到的文件內容信息
        //用鍵值對分別存儲單詞和它出現的次數
        Map<String,Integer> map = new HashMap<String, Integer>();
        try {
            //讀取指定文件DATA.txt,這裏使用的是相對路徑
//          FileInputStream fis = new FileInputStream("J:\\計算機科學與技術\\02 第二學期\\2  軟件工程(代祖華)\\實驗二 詞頻統計\\DATA.txt");
            FileInputStream fis = new FileInputStream("src\\DATA.txt");

            //建立BufferedReader的緩衝流,一次性讀取不少數據,而後按要求分次交給上層調用者
            BufferedReader br = new BufferedReader(new InputStreamReader(fis));
            String str = "";
            try {
                //一行一行讀取
                while ((str = br.readLine()) != null){
                    filecontent = filecontent + str;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }
  • 分割字符串並統計鍵值對
//arrspilt數組用來統計單詞出現的次數
        String [] arrspilt = filecontent.split("[^a-zA-Z]+");
        for (int i=0;i<arrspilt.length;i++){

            //經過鍵名來獲取鍵值
            if (map.get(arrspilt[i]) == null){
                //統計鍵值對
                map.put(arrspilt[i],1);
            }else {
                int count = map.get(arrspilt[i]);
                map.put(arrspilt[i],++count);
            }
        }
  • 對詞頻統計結果進行排序
//利用TreeMap實現Comparator接口
        Comparator<Map.Entry<String, Integer>> valcom = new Comparator<Map.Entry<String,Integer>>() {

            //對詞頻統計結果進行排序
            public int compare(Map.Entry<String, Integer> rst1,Map.Entry<String, Integer> rst2) {
                
                        //降序排序
                int sortrst=rst2.getValue()-rst1.getValue();
            return sortrst;
                
                } 
            
            };
                
    List<Map.Entry<String, Integer>> ordlist = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
                
    // 用sort函數來排序
        Collections.sort(ordlist,valcom);
  • 將詞頻統計結果輸出到指定文件results.txt中
//將詞頻統計結果輸出到指定文件results.txt中
                try {
                    
                    FileWriter fw= new FileWriter("src\\results.txt");
                    BufferedWriter bw= new BufferedWriter(fw); 
                    for (Map.Entry<String, Integer> entry : ordlist) {
                        
                        bw.write(entry.getKey() + ":" + entry.getValue());  
                        bw.newLine();
                    }
                    bw.flush();//刷新
                    bw.close();//關閉
                    System.out.println("詞頻統計結果已輸出到result.txt文件!");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
  • 統計任意單詞在文件中出現次數
List<Map.Entry<String, Integer>> ordlist = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
                    
                // 用sort函數來排序
                Collections.sort(ordlist,valcom);
                
                Scanner sc = new Scanner(System.in); 
                        System.out.println("請輸入想要統計出如今文章中的單詞:"); 
                        String w = sc.next();
            
                for (Map.Entry<String, Integer> entry : ordlist) {
                
                    if(entry.getKey().equals(w)){//找到文件中與鍵盤錄入單詞相同的單詞
                        word=entry.getKey();
                        count2=entry.getValue();
                        flag=1;
                        break;
                    }else{
                        flag=0;
                    }
                    
                }
                if(flag==1){
                    System.out.println("該單詞"+word+"出現的個數爲:"+count2);    
                }else{
                    System.out.println("對不起文章中沒有出現該單詞!");
                }
  • 顯示K個高頻詞及其柱狀圖
System.out.println("注:該文件中共有"+ordlist.size()+"個不一樣的單詞!");
            Scanner sc = new Scanner(System.in); 
                System.out.println("請輸入要查看的高頻詞頻的個數:"); 
                int k = sc.nextInt();
                //String k=sc.next();
                
                //System.out.println(list.size());
                if(k>0&&k<=ordlist.size())//判斷輸入值是否超出範圍
                {
                    System.out.println("----------詞頻最高的前"+k+"個單詞及其柱狀圖-----------");
                    
                    for (Map.Entry<String, Integer> entry : ordlist) {

                        //System.out.println("單詞 "+entry.getKey() + " 出現 " + entry.getValue()+" 次 ");
                        System.out.printf("單詞 "+"%-8s" + "出現 " +"%-3d"+" 次 |",entry.getKey(),entry.getValue()); 

                                //用符號個數來模擬柱狀圖
                            for(int i=entry.getValue();i>0;i--)
                            {
                                System.out.print("⬛");
                            }
                            System.out.println();
                            //System.out.println(entry.getKey() + ":" + entry.getValue());
                            
                            if(--k==0)
                                break;//若是k==0則再也不輸出後面的詞頻                    
                        
                    }
                    System.out.println("------------------------------------------------"); 

                }else{
                    System.out.println("輸入有誤!請從新輸入!");
                }

6. 總結:設計的程序如何實現軟件設計模塊化的原則

模塊化程序設計是指在進行程序設計時將一個大程序按照功能劃分爲若干小程序模塊,每一個小程序模塊完成一個肯定的功能,並在這些模塊之間創建必要的聯繫,經過模塊的互相協做完成整個功能的程序設計方法。模塊化

      在本程序中,須要實現全文單詞個數及其詞頻統計,用戶輸入任意單詞詞頻統計和任意個數高頻詞頻統計及柱狀圖顯示等多個功能,雖然這個程序只是一個小程序,但卻也包含多個功能,若是咱們將這若干個功能放在一個文件中,就會顯得很臃腫,凌亂和複雜,在調試和維護時也很麻煩,最好的方式就是一個功能一個文件,將功能分散開來,用主程序,子程序等框架把軟件的主要結構和流程描述出來,並定義和調試各部分模塊,再經過主函數來實現對其餘功能的調用,以功能塊爲單位進行程序設計,這樣下降錄了程序複雜度,使程序設計,調試等操做簡單化。

7. PSP我的軟件過程

PSP2.1 任務內容 計劃共完成須要的時間(min) 實際完成須要的時間(min)
Planning 計劃 10 10
•Estimate • 估計這個任務須要多少時間,並規劃大體工做步驟 10 10
Development 開發 255 295
••Analysis 需求分析 (包括學習新技術) 10 15
•Design Spec • 生成設計文檔 5 7
•Design Review • 設計複審 (和同事審覈設計文檔) 5 7
•Coding Standard 代碼規範 (爲目前的開發制定合適的規範) 5 6
•Design 具體設計 10 10
•Coding 具體編碼 200 220
•Code Review • 代碼複審 5 10
•Test • 測試(自我測試,修改代碼,提交修改) 15 20
Reporting 報告 13 15
••Test Report • 測試報告 4 3
•Size Measurement 計算工做量 4 4
•Postmortem & Process Improvement Plan • 過後總結 ,並提出過程改進計劃 5 8

      從本次這個詞頻統計程序的開發過程來看,我在作這項工做時是用來很多的時間,尤爲是在開發過程當中的編碼設計階段,因爲很長時間沒有再寫代碼,關於java好多知識都忘得差很少了,因此在編碼時須要耗費時間來查資料,來糾錯改錯,但也基本完成了本次任務,看來往後要多增強代碼的編寫練習。

相關文章
相關標籤/搜索