Java实现的词频统计——功能改进
2016-09-12 15:22
375 查看
本次改进是在原有功能需求及代码基础上额外做的修改,保证了原有的基础需求之外添加了新需求的功能。
功能:
1. 小文件输入——从控制台由用户输入到文件中,再对文件进行统计;
2.支持命令行输入英文作品的文件名;
3.支持命令行输入存储有英文作品文件的目录名,批量统计;
4.从控制台读入英文单篇作品,重定向输入流。
实现:
1.判断输入方式,如果从命令行传递参数则直接对文件进行统计;如果未传递参数,其方式同控制台相同,由用户从标准输入流输入到文件,再对文件进行词频统计。这里如果传入文件路径时会对其是否是文件夹进行判断,如果是文件夹,则对其目录中的文件进行统计。
2.对ByValueComparator类做了修改,使其能够按词频降序排列的同时,对同频率的单词进行升序排列。
3.与上一次相比,为了方便调用,将对文件进行统计操作的代码归入新的类FileProccessing。同时将readline()改为read(char[] c),解决了当一行字符过多时报错的问题。当进行统计的文件过大时,原本输出到屏幕会自动改为输出到文件中,避免了因输出而占用了大部分时间,同时方便用户查阅(默认输出到工程目录下)。
其中有个小细节:程序中char数组默认大小为64,当读到最后一块时,字符不足64个时,多余未读入字符的数组元素默认为'\0',拆分之后输出结果中会多出一项“ ——1”。因此,在StringTokenizer方法中要录入"\0"作为分隔字符。
读入文件并进行统计,结果存入到hashmap中:
判断输出内容多少,自动匹配标准输出还是文件输出。其中运用了正则替换,用来打印当前文件名。同时还对总单词量及词汇量进行了统计:
运行结果:
1.命令行标准输入界面:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912142300742-955205721.png)
2.执行结果:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912142411039-1581001844.png)
3.控制台界面:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912162005086-1006252341.png)
4.命令行传入文件:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135232773-276990391.png)
5.同时传入大文件及文件夹:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135731742-1566927264.png)
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135909820-640288748.png)
6.重定向输入:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135105977-1701877762.png)
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912161500164-364331225.png)
代码地址:
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
功能:
1. 小文件输入——从控制台由用户输入到文件中,再对文件进行统计;
2.支持命令行输入英文作品的文件名;
3.支持命令行输入存储有英文作品文件的目录名,批量统计;
4.从控制台读入英文单篇作品,重定向输入流。
实现:
1.判断输入方式,如果从命令行传递参数则直接对文件进行统计;如果未传递参数,其方式同控制台相同,由用户从标准输入流输入到文件,再对文件进行词频统计。这里如果传入文件路径时会对其是否是文件夹进行判断,如果是文件夹,则对其目录中的文件进行统计。
if (args.length == 0) { Scanner in = new Scanner(System.in); FileWriter out = new FileWriter("Content.txt"); System.out.println("请输入内容,最后以Q结束:"); while (in.hasNext()) { out.write(in.nextLine()+"\r\n"); } out.close(); in.close(); new FileProccessing("Content.txt"); } for (int i = 0; i < args.length; i++) { String FileName = args[i]; File fs = new File(FileName); if (fs.isDirectory()) { File[] filelist = fs.listFiles(); for (int n = 0; n < filelist.length; n++) { new FileProccessing(filelist .getAbsolutePath()); } } else { new FileProccessing(FileName); } }
2.对ByValueComparator类做了修改,使其能够按词频降序排列的同时,对同频率的单词进行升序排列。
public class ByValueComparator implements Comparator<Entry<String,Integer>> { Map<String, Integer> hashmap; public ByValueComparator(Map<String, Integer> hm) { this.hashmap = hm; } @Override public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { // TODO Auto-generated method stub if (o1.getValue().compareTo(o2.getValue()) == -1) { return 1; } else if (o1.getValue().compareTo(o2.getValue()) == 0) { return o1.getKey().compareTo(o2.getKey()); //单次出现频率相同时,对单词进行升序排列 } else { return -1; } } }
3.与上一次相比,为了方便调用,将对文件进行统计操作的代码归入新的类FileProccessing。同时将readline()改为read(char[] c),解决了当一行字符过多时报错的问题。当进行统计的文件过大时,原本输出到屏幕会自动改为输出到文件中,避免了因输出而占用了大部分时间,同时方便用户查阅(默认输出到工程目录下)。
其中有个小细节:程序中char数组默认大小为64,当读到最后一块时,字符不足64个时,多余未读入字符的数组元素默认为'\0',拆分之后输出结果中会多出一项“ ——1”。因此,在StringTokenizer方法中要录入"\0"作为分隔字符。
读入文件并进行统计,结果存入到hashmap中:
int i = 0; char[] c = new char[64]; String thelast = ""; String wordpart = ""; while ((i = br.read(c)) > 0) { wordpart = ""; int m = i - 1; while (Character.isLetter(c[m])) { wordpart = String.valueOf(c[m]) + wordpart; c[m] = ' '; m--; } String s = thelast + String.valueOf(c); StringTokenizer st = new StringTokenizer(s, " ,.!?\"\';:0123456789\n\r\t“”‘’·——-=*/()[]{}…()【】{}\0"); // 用于切分字符串 while (st.hasMoreTokens()) { String word = st.nextToken(); if (hm.get(word) != null) { int value = ((Integer) hm.get(word)).intValue(); value++; hm.put(word, new Integer(value)); } else { hm.put(word, new Integer(1)); } } thelast = wordpart; } if (!wordpart.isEmpty()) { if (hm.get(wordpart) != null) { int value = ((Integer) hm.get(wordpart)).intValue(); value++; hm.put(wordpart, new Integer(value)); } else { hm.put(wordpart, new Integer(1)); } }
判断输出内容多少,自动匹配标准输出还是文件输出。其中运用了正则替换,用来打印当前文件名。同时还对总单词量及词汇量进行了统计:
int NumofWord = 0; Iterator iter = hm.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); NumofWord += (Integer) entry.getValue(); } String reg = ".*\\\\(.*)"; String name = filename.replaceAll(reg, "$1"); if (hm.size() > 100) { FileWriter result = new FileWriter("Result.txt", true); result.write("~~~~~~~~~~~~~~~~~~~~\r\n"); result.write(name.substring(0, name.lastIndexOf(".")) + "\r\n"); result.write("number of the words:" + NumofWord + "\r\n"); result.write("totals:" + hm.size() + "\r\n"); for (Map.Entry<String, Integer> str : ll) { result.write(str.getKey() + "——" + str.getValue() + "\r\n"); } result.write("~~~~~~~~~~~~~~~~~~~~\r\n"); System.out.println("由于" + name.substring(0, name.lastIndexOf(".")) + "文件过大,输出到文件Result中。"); result.close(); } else { System.out.println("~~~~~~~~~~~~~~~~~~~~"); System.out.println(name.substring(0, name.lastIndexOf("."))); System.out.println("number of the words:" + NumofWord); System.out.println("totals:" + hm.size()); for (Map.Entry<String, Integer> str : ll) { System.out.println(str.getKey() + "——" + str.getValue()); } System.out.println("~~~~~~~~~~~~~~~~~~~~"); }
运行结果:
1.命令行标准输入界面:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912142300742-955205721.png)
2.执行结果:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912142411039-1581001844.png)
3.控制台界面:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912162005086-1006252341.png)
4.命令行传入文件:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135232773-276990391.png)
5.同时传入大文件及文件夹:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135731742-1566927264.png)
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135909820-640288748.png)
6.重定向输入:
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912135105977-1701877762.png)
![](https://images2015.cnblogs.com/blog/1019195/201609/1019195-20160912161500164-364331225.png)
代码地址:
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
相关文章推荐
- java IO流读取保存图片文件
- leetCode练习(3)
- 使用Eclipse开发Android报错:Project has no target set. Edit the project properties to set one.
- spring quartz分布式任务计划
- java算法-优化360开机时间服务端写法
- Java web图片验证功能实现二
- java web中图片验证码功能实现
- thinking in java test chapter9接口(1)~(10)
- Spring的核心之IoC和AOP
- Spring事务管理
- Spring事务传播及隔离
- 我的第一个struts2(基于myeclipce2016)
- Struts2文件上传和下载
- struts2
- java web文件下载功能实现
- java esl连接freeswitch(二)之事件监听
- Java Spring 事务管理
- spring3的propagation的取值REQUIRED与REQUIRED_NEW的区别
- java中volatile和transient关键字详解附代码示例
- java poi读取Excel文件,数字变成科学计数法及数字自动带上“.0”的处理办法