1. 程式人生 > 實用技巧 >張兵傑 20200917-2 詞頻統計

張兵傑 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 ①未讀明白題意,耗費很多時間