初来乍到,请多关照。本人胆小怯懦的小猿一只,时常靠搬运代码和抱学霸大腿维持生(cheng)计(ji)。在老师的推(qiang)荐(po)之下来到园子班门弄斧,望得大神指点,早日得道成仙。
上周的软件工程课上布置了这个作业:写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的10个词打印出来。
拿到题目后,还在犹豫使用哪种语言时,班上的牛牛们早已纷纷在园子里贴出了博客。博览群博之后,经深思熟虑(为了合作项目时不给大腿拖后腿),我选择了java。
因为只是作为一门限选课,平时也没有太多涉猎,对java这门语言的了解并不多,所以在开工之前查了很多相关的资料,发现用hashmap是个不错的办法,于是就从这个方面着手做了。
第一步,读取文件,这一步处理的比较简单,没有设置输入路径读取任意文件,只是在代码中指定了要读的文件。[捂脸||]
1 import java.util.*; 2 import java.io.*; 3 public class wordrate { 4 public static void main(String[] args) throws Exception{ 5 FileReader in =new FileReader("jobs.txt"); //建立文件输入流 6 BufferedReader bin=new BufferedReader(in); //建立缓冲输入流
第二步,提取并处理文件中的单词。首先将所有的英文字母都转化为小写,当然也考虑到了单词的缩写问题,然后将除"'"外的非字母的字符都转化为一个空格,最后用
words[]= file.split("\\s+");语句将单词提取出来存入到words[]中。
1 String str; 2 String file=null; 3 while((str =bin.readLine())!=null){ 4 file+=str; 5 } 6 file = file.toLowerCase();// 将所有字母化为小写 7 file = file.replaceAll("[^a-z']|\\s+|\t|\r", " "); // 将非字母字符、多个空格回车换行均化为一个空格 8 String words[]= file.split("\\s+");// 取出单词,并将单词存入数组中
第三步,创建一个hashmap,将数组中存放的单词导入其中,用于统计单词出现的次数。
这个我也是才学习到的用法的,学过数据结构后,对哈希表并不陌生,HashMap是Hashtable的轻量级实现(非线程安全的实现),hashmap 是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许null key和null value,而hashtable不允许。
在这里hashmap中的键(key)表示单词,值(value)表示单词出现的次数。一个单词第一次出现,value初始化为1,同样的单词没多出现一次value的值+1。
1 Map<String, Integer> hash_Data = new HashMap<String, Integer>(); 2 for (int i = 0; i < words.length; i++) 3 { 4 String key = words[i]; //key对应单词 5 if (hash_Data.get(key) != null) 6 { 7 int value = ((Integer) hash_Data.get(key)).intValue(); //value对应单词出现的频率,单词已在map中存在则value+1 8 value++; 9 hash_Data.put(key, new Integer(value)); 10 } else { 11 hash_Data.put(key, new Integer(1)); //单词未在map中存在则value初始化为1 12 } 13 }
第四步,用 Collections.sort方法对hashmap中的项按照value的值进行排序。Comparator是个接口,主要用来比较两个对象。
Map是java中的接口,Map.Entry是Map的一个内部接口.Map提供了一些常用方法,如keySet()、entrySet()等方法,keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry。Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry<K,V>。它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。
重写compare()方法value的值进行比较后排序。
1 List<Map.Entry<String, Integer>> list_Data = new ArrayList<Map.Entry<String, Integer>>(hash_Data.entrySet()); 2 Collections.sort(list_Data, new Comparator<Map.Entry<String, Integer>>(){ 3 public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2){ 4 if(o2.getValue()!=null&&o1.getValue()!=null&&o2.getValue().compareTo(o1.getValue())>0){ 5 return 1; 6 }else{ 7 return -1; 8 }}});
最后,将排好的结果进行输出。
1 System.out.println("频率最高的十个单词:"); 2 for (int i = 0; i <10; i++) { 3 String id = list_Data.get(i).toString(); 4 System.out.print("第"+(i+1)+"."); 5 System.out.println(id); 6 } 7 } 8 }
以上就是我本次作业的全部代码。
运行截图如下:
这次作业写的代码,比较简短也略显粗糙。比起辉哥宿舍一群大神的程序能分析5M的文章,我的才3K就over了。。。。简直弱爆了,欲哭无泪。看到了自己和别人的差距,最无奈的也是知道自己的弱点却不知如何改进,唯一的办法只能是多看多想多做,大神也不是一朝练成的。以后会在这里活跃起来,多多与人交流,长长知识,多学一些实用的技能。也希望各路大神可以不吝赐教助我成长。谢谢!