Java實現的詞頻統計——功能改進


  本次改進是在原有功能需求及代碼基礎上額外做的修改,保證了原有的基礎需求之外添加了新需求的功能。

功能:

  1. 小文件輸入——從控制台由用戶輸入到文件中,再對文件進行統計;

  2.支持命令行輸入英文作品的文件名;

  3.支持命令行輸入存儲有英文作品文件的目錄名,批量統計;

  4.從控制台讀入英文單篇作品,重定向輸入流。

實現:

  1.判斷輸入方式,如果從命令行傳遞參數則直接對文件進行統計;如果未傳遞參數,其方式同控制台相同,由用戶從標准輸入流輸入到文件,再對文件進行詞頻統計。這里如果傳入文件路徑時會對其是否是文件夾進行判斷,如果是文件夾,則對其目錄中的文件進行統計。

 1 if (args.length == 0) {
 2             Scanner in = new Scanner(System.in);
 3             FileWriter out = new FileWriter("Content.txt");
 4             
 5             System.out.println("請輸入內容,最后以Q結束:");
 6 
 7             while (in.hasNext()) {
 8                 out.write(in.nextLine()+"\r\n");
 9             }
10             out.close();
11             in.close();
12             
13             new FileProccessing("Content.txt");
14         }
15         for (int i = 0; i < args.length; i++) {
16             String FileName = args[i];
17             File fs = new File(FileName);
18             if (fs.isDirectory()) {
19                 File[] filelist = fs.listFiles();
20                 for (int n = 0; n < filelist.length; n++) {
21                     new FileProccessing(filelist[n].getAbsolutePath());
22                 }
23 
24             } else {
25                 new FileProccessing(FileName);
26             }
27         }

  2.對ByValueComparator類做了修改,使其能夠按詞頻降序排列的同時,對同頻率的單詞進行升序排列。

 1 public class ByValueComparator implements Comparator<Entry<String,Integer>> {
 2     Map<String, Integer> hashmap;
 3     public ByValueComparator(Map<String, Integer> hm) {
 4         this.hashmap = hm;
 5     }
 6 
 7     @Override
 8     public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
 9         // TODO Auto-generated method stub
10 
11         if (o1.getValue().compareTo(o2.getValue()) == -1) {
12             return 1;
13         } else if (o1.getValue().compareTo(o2.getValue()) == 0) {
14             return o1.getKey().compareTo(o2.getKey());  //單次出現頻率相同時,對單詞進行升序排列
15         } else {
16             return -1;
17         }
18     }
19 }

  3.與上一次相比,為了方便調用,將對文件進行統計操作的代碼歸入新的類FileProccessing。同時將readline()改為read(char[] c),解決了當一行字符過多時報錯的問題。當進行統計的文件過大時,原本輸出到屏幕會自動改為輸出到文件中,避免了因輸出而占用了大部分時間,同時方便用戶查閱(默認輸出到工程目錄下)。

  其中有個小細節:程序中char數組默認大小為64,當讀到最后一塊時,字符不足64個時,多余未讀入字符的數組元素默認為'\0',拆分之后輸出結果中會多出一項“    ——1”。因此,在StringTokenizer方法中要錄入"\0"作為分隔字符。

  讀入文件並進行統計,結果存入到hashmap中:

 1         int i = 0;
 2         char[] c = new char[64];
 3         String thelast = "";
 4         String wordpart = "";
 5         while ((i = br.read(c)) > 0) {
 6             wordpart = "";
 7 
 8             int m = i - 1;
 9             while (Character.isLetter(c[m])) {
10                 wordpart = String.valueOf(c[m]) + wordpart;
11                 c[m] = ' ';
12                 m--;
13             }
14             String s = thelast + String.valueOf(c);
15             StringTokenizer st = new StringTokenizer(s, " ,.!?\"\';:0123456789\n\r\t“”‘’·——-=*/()[]{}…()【】{}\0"); // 用於切分字符串
16 
17             while (st.hasMoreTokens()) {
18                 String word = st.nextToken();
19                 if (hm.get(word) != null) {
20                     int value = ((Integer) hm.get(word)).intValue();
21                     value++;
22                     hm.put(word, new Integer(value));
23                 } else {
24                     hm.put(word, new Integer(1));
25                 }
26             }
27             thelast = wordpart;
28         }
29         if (!wordpart.isEmpty()) {
30             if (hm.get(wordpart) != null) {
31                 int value = ((Integer) hm.get(wordpart)).intValue();
32                 value++;
33                 hm.put(wordpart, new Integer(value));
34             } else {
35                 hm.put(wordpart, new Integer(1));
36             }
37         }

  判斷輸出內容多少,自動匹配標准輸出還是文件輸出。其中運用了正則替換,用來打印當前文件名。同時還對總單詞量及詞匯量進行了統計:

 1         int NumofWord = 0;
 2         Iterator iter = hm.entrySet().iterator();
 3         while (iter.hasNext()) {
 4             Map.Entry entry = (Map.Entry) iter.next();
 5             NumofWord += (Integer) entry.getValue();
 6         }
 7         String reg = ".*\\\\(.*)";
 8         String name = filename.replaceAll(reg, "$1");
 9         if (hm.size() > 100) {
10 
11             FileWriter result = new FileWriter("Result.txt", true);
12 
13             result.write("~~~~~~~~~~~~~~~~~~~~\r\n");
14             result.write(name.substring(0, name.lastIndexOf(".")) + "\r\n");
15             result.write("number of the words:" + NumofWord + "\r\n");
16             result.write("totals:" + hm.size() + "\r\n");
17             for (Map.Entry<String, Integer> str : ll) {
18                 result.write(str.getKey() + "——" + str.getValue() + "\r\n");
19             }
20 
21             result.write("~~~~~~~~~~~~~~~~~~~~\r\n");
22 
23             System.out.println("由於" + name.substring(0, name.lastIndexOf(".")) + "文件過大,輸出到文件Result中。");
24             result.close();
25         } else {
26             System.out.println("~~~~~~~~~~~~~~~~~~~~");
27             System.out.println(name.substring(0, name.lastIndexOf(".")));
28             System.out.println("number of the words:" + NumofWord);
29             System.out.println("totals:" + hm.size());
30             for (Map.Entry<String, Integer> str : ll) {
31                 System.out.println(str.getKey() + "——" + str.getValue());
32             }
33 
34             System.out.println("~~~~~~~~~~~~~~~~~~~~");
35         }

 

運行結果:

  1.命令行標准輸入界面:

  

  2.執行結果:

  

  3.控制台界面:

  

   4.命令行傳入文件:

  

   5.同時傳入大文件及文件夾:

   

  

   6.重定向輸入:

  

  

 

代碼地址:

  HTTPS   https://coding.net/u/regretless/p/WordFrequencyCount/git

  SSH      git@git.coding.net:regretless/WordFrequencyCount.git

  GIT       git://git.coding.net/regretless/WordFrequencyCount.git

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM