本次改進是在原有功能需求及代碼基礎上額外做的修改,保證了原有的基礎需求之外添加了新需求的功能。
功能:
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