要求0:作業要求位址【https://edu.cnblogs.com/campus/nenu/2016CS/homework/2110】
要求1:git倉庫位址【https://git.coding.net/yangmx2016011904/wf.git】
要求2:
PSP | 任務内容 | 計劃時間(min) | 完成時間(min) |
Planning | 計劃 | 30 | 60 |
Estimate | 估計這個任務需要多少時間,并規劃大緻工作步驟 | | |
Development | 開發 | 630 | 910 |
Analysis | 需求分析 | 40 | |
Design Spec | 生成文檔 | 20 | |
Design Review | 設計複審 | | |
Coding Standard | 代碼規範 | | |
Design | 具體設計 | | 120 |
Coding | 具體編碼 | 420 | 540 |
Code Review | 代碼複審 | | |
Test | 測試 | | 80 |
Reporting | 報告 | 160 | 400 |
Test Report | 測試報告 | | |
Size Measurement | 計算工作量 | | |
Postmortem & Process Improvement Plan | 事後總結, 并提出過程改進計劃 | | 50 |
功能子產品 | 具體階段 | 預計時間(min) | 實際時間(min) |
功能1 | 測試完善 | 10 | 150 |
功能2 | | | 25 |
功能3 | | | 240 35 |
分析預估耗時和實際耗時的差距原因:
在整個項目的完成過程中,我在具體編碼的這個方面花費的時間最多,我認為主要有兩方面原因:
1.在計劃和需求分析,将有些問題想的過于簡單,在程式設計中不斷有新的問題産生,一個一個問題解決起來花費了一些超過預期的時間
2.我對于編寫程式還不是很熟悉,是以突然要開始上手具體編寫程式時就有一些懵了。由于不是很熟悉,是以需要通過大量的查詢才能完成,但在查閱資料後在具體使用的時候還是會出現這樣那樣的錯誤,這就大大拖慢了我的速度。經過這一次的個人項目,讓我認識到了我在實踐方面的不足,也激勵我在今後的學習中多動手,多實踐。
項目實作的過程要比我想象中艱難,花費的時間也是遠遠超過我的預期。但也讓我從中收獲到很多,不斷發現問題,分析問題,解決問題的過程也讓我對java語言有了更好的應用和了解。
要求3:
解題思路描述:
在看到統計文本檔案(檔案名字尾為txt)中的單詞出現次數這個題目時,我一頭霧水,感覺文本很長,統計要花費很多時間,于是我便開始在網上查閱有關統計詞彙的介紹,看了很多的部落格、代碼,慢慢學習到了解決這個問題的思路,我覺得看到一道題之後的思維方式很重要,有了思路之後才能慢慢解決接下來遇到的困難。通過學習參考網上一些類似問題的解決方法,我确定了這道題的解題思路:就是無論多長的文章,都把它看成一句話,是個字元串,這個字元串中可能不僅有英文單詞,還有一些标點符号,而這些空格、非字母正好是分割函數中的分割标準,這樣一來,在将這個長長的字元串進行分割後,剩餘的就是一個又一個需要計數統計的單詞,進而實作功能1。功能2主要是擷取某檔案夾下的所有檔案名,将檔案名按字典序排序後傳回指定檔案。功能3則是對單詞出現的頻率進行排序,再按要求輸出出現次數最多的前N個單詞。
簡述代碼并展示部分代碼片段:
我一共使用了四個類, 其中wfone、wftwo、wfthree分别對應功能1、2、3,并用類wf作為測試類。在實作功能1時,單詞不區分大小寫,是以将其全部轉換為小寫,使用了word = word.toLowerCase(),然後空格和非字母字元進行分割并存入數組,利用循環,使用isLegal()函數判斷是否為合法單詞,并利用map函數的特點,來統計單詞的數量;在實作功能2時,首先在檔案夾中讀取所有檔案并參考功能1完成的;功能3則是通過增加比較器來實作的。感覺自己學會的東西太少,是以很多都需要找資料看部落格,但在這個解決問題的過程中自己也學會了很多知識點,是有很大收獲的。在其中很大的收獲就是關于map函數的一些了解,map這個集合函數的使用,利用它的一些特性,健值不重複,可以統計有多少不重複的單詞;将它的兩個屬性一個設定為字元串類型,來記錄單詞,另一個設計成整型,來記錄其個數。在向其中添加值時,利用myMap.containsKey(word[i])語句進行判斷,如果map中已有,則其數量值加1,若比對不上,則将數量值記為1。
接下來是一些代碼展示:
String str=characters.toString().toLowerCase();//将字元全部轉化為小寫
String[] word = str.split("[^a-zA-Z0-9]");//按空格和非字母進行分割
int num =0;
Map<String,Integer> myMap = new TreeMap<String,Integer>();//分割後存入數組
//周遊數組将其存入Map<String,Integer>中
String regex="^[a-zA-Z][a-zA-Z0-9]*$";
Pattern p = Pattern.compile(regex);
for(int i=0;i<word.length;i++) {
Matcher m =p.matcher(word[i]);
if(m.matches()) {
if(myMap.containsKey(word[i])) {
num = myMap.get(word[i]);
myMap.put(word[i], num+1);
}
else {
myMap.put(word[i], 1);
}
}
}//判斷是否為合法單詞 将合法單詞存入Map
List<Map.Entry<String, Integer>> list =new ArrayList<Map.Entry<String,Integer>>(myMap.entrySet());//Map轉換成list進行排序
System.out.println("total"+" "+list.size()+"\n");
for(int i=0;i<word.length;i++) {
if(myMap.containsKey(word[i])) {
System.out.println(word[i]+" "+myMap.get(word[i]));
myMap.remove(word[i]);
}//在Map集合中不應該利用get()方法來判斷是否存在某個鍵,而應該利用containsKey()方法來判斷
}
bufferedReader.close();
public String readDir(String filepath){
File file = new File(filepath);
String[] filelist = file.list();
String[] characterlist = new String [filelist.length];
for(int i=0;i<filelist.length;i++) {
File readfile = new File(filepath+"\\"+filelist[i]);
characterlist[i]=readfile.getName();
}
List<String> list = (List<String>)Arrays.asList(characterlist);
Collections.sort(list);
String[] paths = list.toArray(new String[0]);
return paths[0];
}// 使用readDir()函數讀取某檔案夾下的所有檔案
Collections.sort(list,new Comparator<Map.Entry<String, Integer>>(){
public int compare(Entry<String,Integer> e1,Entry<String,Integer> e2) {
return e2.getValue().compareTo(e1.getValue());
}
}); //使用比較器進行排序
運作截圖:
個人感想:
在完成項目的過程中,從最初的找不到方向到開始整理思路,解決遇到的一個又一個問題,我感覺做什麼事都是要一步一步來的,這樣我想到了《建構之法》中第三章中,通過大家小時候經常玩的魔方引出技能的反面是解決問題,通過不斷地練習,把那些低層次的問題都解決了,變成不用經過大腦的自動操作,然後才有時間和腦力來解決較高層次的問題。學習也是個循序漸進的過程。