張兵傑 20200917-2 詞頻統計
詞頻統計 SPEC
1. 功能1小檔案輸入。 為表明程式能跑,結果真實而不是迫害老五,請他親自鍵
盤在控制檯下輸入命令。
重點難點:
(1)檔案讀取
/**傳入txt路徑讀取txt檔案 * @param txtPath * @return 返回讀取到的內容 */ public static String readTxt(String txtPath) { File file = new File(txtPath); if(file.isFile() && file.exists()){ try{ FileInputStream fileInputStream = new FileInputStream(file); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); StringBuffer sb = new StringBuffer(); String text= null; while((text = bufferedReader.readLine()) != null){ sb.append(text); sb.append('\n'); //增加換行符 } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } }else{ System.out.println("File not exist"); } return null; }
(2)文字處理分割,次數統計
①首先將所有大寫換小寫,用非單詞符來做分割,分割出來的就是一個個單詞。
②用Map鍵值對來儲存單詞與相應的次數。
③使用set集合,利用set的不可重複性,統計單詞總數,則不會出現重複現象。
content = content.toLowerCase();//將所有大寫換小寫 String[] words = content.split("\\W+");//用非單詞符來做分割,分割出來的就是一個個單詞 length = words.length; HashMap<String, Integer > hashMap = new HashMap<String,Integer>(); Set<String> set = new HashSet<>();//keySet將Map中所有的鍵存入到set集合中 for(String word : words){ if(word != " "){ if(set.contains(word)){ // 如果這個單詞已經存在,單詞次數加1,重新存放 Integer number = hashMap.get(word); number++; hashMap.put(word, number); //重新放一個相同的key,會自動覆蓋value }else{ hashMap.put(word, 1);//在map,set中存放此單詞 set.add(word); } } } sum = set.size();//單詞總數 System.out.println("total " + sum + " words");
2.功能2支援命令列輸入英文作品的檔名,請老五親自錄入。
重點/難點
(1)拼接含空格的檔名稱,迴圈引數時,通過空格連線,注意最後使用trim去除檔名末尾的空格。
if(length > 0){ if(length == 1){ path = basicPath + args[0]; File file = new File(path); if(file.isDirectory()){ }else if(file.isFile()){ flag = true; } }else if(length > 1){ if(length == 2 && args[1].equals("-s")){ //為第一種情況,含"-s" flag = true; //是檔案 path = basicPath + directoryPath + args[1]+ ".txt"; }else{ flag = true; //是檔案 String fileName = ""; for (String arg : args){ //拼接含空格的檔案 fileName = fileName + arg; fileName = fileName + " "; } fileName = fileName.trim(); //去末尾空格 path = basicPath + directoryPath + fileName + ".txt"; System.out.println(path); } } if(flag){ String content = readTxt(path); if(content.length() > 0) { countBigTxt(content); } } }
3.功能3支援命令列輸入儲存有英文作品檔案的目錄名,批量統計。因為單詞量巨大,只列出出現次數最多的10個單詞。
重點/難點
(1) 判斷輸入的是檔名還是目錄。若是目錄,則讀取目錄下的全部內容,分別進行統計。
/**讀取資料夾下所有檔名 * @param file */ public static List<File> getFiles(File file){ List<File> files = new ArrayList<>(); File[] subFiles = file.listFiles(); for(File f : subFiles){ files.add(f); } return files; }
if(file.isDirectory()){ List<File> files = getFiles(file); for (File subFile : files){ String content = readTxt(subFile.getAbsolutePath()); if(content.length() > 0) { System.out.println(subFile.getName()); countBigTxt(content); System.out.println("----"); } } }else if(file.isFile()){ flag = true; //是檔案 }
(2)列出出現次數最多的10個單詞 將map根據其中每個value值大小進行從大到小排序。使用Collections.sort函式,重寫compare方法。
List<Map.Entry<String, Integer>> list = new ArrayList<>(hashMap.entrySet()); //按照value值,從大到小排序 Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { return o2.getValue() - o1.getValue(); } }); int i = 0; for (Map.Entry s : list) { System.out.println(s.getKey()+" "+s.getValue()); if(i >= 10) break; i++; }
4.功能4從控制檯讀入英文單篇作品,這不是為了打臉老五,而是為了向你女朋
友炫酷,表明你能提供更適合嵌入指令碼中的作品(或者如她所說,不過是更靈活
的介面)。如果讀不懂需求,請教師兄師姐,或者 bing: linux 重定向,儘管
這個功能在windows下也有,搜尋關鍵詞中加入linux有利於迅速找到。
功能4從控制檯讀入英文單篇作品,這不是為了打臉老五,而是為了向你女朋
友炫酷,表明你能提供更適合嵌入指令碼中的作品(或者如她所說,不過是更靈活
的介面)。如果讀不懂需求,請教師兄師姐,或者 bing: linux 重定向,儘管
這個功能在windows下也有,搜尋關鍵詞中加入linux有利於迅速找到。
>wf -s < the_show_of_the_ring
total 176
the 6
a 3
festival 2
dead 2
for 2
功能 | 預計花費時間(min) | 實際花費時間(min) | 時間差(min) | 原因 |
功能1 | 100min | 194min | +94min |
①由於對單詞定義考慮太多,多次變換單詞分割方法 ②對正則表示式不熟悉 |
功能2 | 60min | 92min | +32min |
①修改統計單詞數量的方法,由最初for迴圈判斷是否重複,改為使用Set集合。 ②拼接空目錄 |
功能3 | 60min | 98min | +38min | ①做完此功能後,第一次嘗試進行將jar轉為exe檔案,耗費很多時間 |
功能4 | 80min | 42min | -38min | ①未讀明白題意,耗費很多時間 |