这次软件工程的一个个人项目是一个文本单词统计的小程序。
时间 | 8:00-9:00 | 9:00-10:45 | 11:00-15:00 | 次日8:00-9:30 | 10:00-11:30 |
动作 | 查阅资料 | 对1、2两部分代码的完成 | 对出现问题部分的调试 | 通过讨论完成调试 | 完善代码 |
因此它要实现的是读取文件,并能统计其中不同单词出现的次数,并按照由高到低的出现频数排序,并输出前10的单词及其出现的次数。
通过分析,则要实现以下2步:
1.对文本文件的读取,将一个一个的单词分离出来,并对单词进行统计。
在这里我们要用到文件的输入输出流(以下为部分主要代码):
1 TreeMap<String, Integer> map = new TreeMap<String,Integer >(); 2 try 3 { 4 fr=new BufferedReader(new FileReader(filename)); 5 System.out.println("======================"); 6 String len; 7 while((len=fr.readLine())!=null) 8 { 9 word=len.split(" |,"); 10 System.out.println(len); 11 for( i=0;i<(word).length;i++) 12 { 13 String key=((word))[i].toLowerCase(); 14 if(((word))[i].length()>0) 15 { 16 if(map.get(key)==null) 17 { 18 map.put(key, 1);cd++; 19 } 20 else 21 { 22 int value=map.get(key).intValue(); 23 value++; 24 map.put(key, value); 25 } 26 } 27 } 28 } 29 System.out.println("======================"); 30 } 31 catch (Exception e) 32 { 33 System.out.println("出现异常!"+e.toString()); 34 check=false; 35 // TODO: handle exception 36 }
在这里其实用到了java中的map集的结构。通过生成一个新的treemap对象,将单词及单词出现的次数分别对应到treemap<String,Integer>中,这样的结构方便使用(当然在排序是并未有很好的作用)。值得注意的是:map这样的泛型集有多种:Hashmap,Treemap等等。Treemap 的特点就是在输出时它是按照key值进行排序输出,及在这里它可以按照单词首字母排序输出。
2.对单词出现的次数进行排序。
if(check!=false) { try { System.out.println("单词的个数为(不重复的):"+cd); }catch(Exception e2) { System.out.println("异常处理2"); } Iterator<String> it= map.keySet().iterator(); Integer tempcount; String tempname=null; Integer[] sortc=new Integer[cd]; String[] sortn = new String[cd] ; i=0; while(it.hasNext()){ String name = (String) it.next(); Integer count=map.get(name); sortc[i]=count; sortn[i]=name; i++; } for(i=0;i<cd-1;i++) { for(j=0;j<cd-i-1;j++) { if((sortc)[j]<(sortc)[j+1]) { tempname=(sortn)[j]; tempcount=(sortc)[j]; (sortn)[j]=(sortn)[j+1]; (sortc)[j]=(sortc)[j+1]; ((sortn))[j+1]=tempname; (sortc)[j+1]=tempcount; } } } System.out.println("输出出现次数最高的10个单词:"); for(i=0;i<10;i++) { System.out.println((sortn)[i].toString()+" "+" "+(sortc)[i]); } } }
在这里使用的是冒泡排序法,这样的效率会高一点。通过将treemap中的数据一一对应到两个数组中(注意:前面要统计好数组的长度,这样才能很好地定义数组)。
现在将完整的代码贴上:
1 import java.io.*; 2 import java.io.FileReader; 3 import java.util.*; 4 public class test1 { 5 public static void main(String[] args) { 6 System.out.println("请输入文件完整路径及名称"); 7 Scanner in = new Scanner(System.in); 8 String filename=in.next(); 9 System.out.println(filename); 10 BufferedReader fr=null; 11 String[] word = null; 12 int i = 0,j; 13 int cd=0; 14 boolean check=true; 15 TreeMap<String, Integer> map = new TreeMap<String,Integer >(); 16 try 17 { 18 fr=new BufferedReader(new FileReader(filename)); 19 System.out.println("======================"); 20 String len; 21 while((len=fr.readLine())!=null) 22 { 23 word=len.split(" |,"); 24 System.out.println(len); 25 for( i=0;i<(word).length;i++) 26 { 27 String key=((word))[i].toLowerCase(); 28 if(((word))[i].length()>0) 29 { 30 if(map.get(key)==null) 31 { 32 map.put(key, 1);cd++; 33 } 34 else 35 { 36 int value=map.get(key).intValue(); 37 value++; 38 map.put(key, value); 39 } 40 } 41 } 42 } 43 System.out.println("======================"); 44 } 45 catch (Exception e) 46 { 47 System.out.println("出现异常!"+e.toString()); 48 check=false; 49 // TODO: handle exception 50 } 51 /*for(i=0;i<word.length;i++) 52 { 53 if(word[i].contains(",")) 54 { 55 pureword=word[i].split(","); 56 } 57 }*/ 58 if(check!=false) 59 { 60 try 61 { 62 System.out.println("单词的个数为(不重复的):"+cd); 63 }catch(Exception e2) 64 { 65 System.out.println("异常处理2"); 66 } 67 68 Iterator<String> it= map.keySet().iterator(); 69 70 Integer tempcount; 71 String tempname=null; 72 Integer[] sortc=new Integer[cd]; 73 String[] sortn = new String[cd] ; 74 i=0; 75 while(it.hasNext()){ 76 77 String name = (String) it.next(); 78 Integer count=map.get(name); 79 sortc[i]=count; 80 sortn[i]=name; 81 i++; 82 } 83 for(i=0;i<cd-1;i++) 84 { 85 for(j=0;j<cd-i-1;j++) 86 { 87 if((sortc)[j]<(sortc)[j+1]) 88 { 89 tempname=(sortn)[j]; 90 tempcount=(sortc)[j]; 91 (sortn)[j]=(sortn)[j+1]; 92 (sortc)[j]=(sortc)[j+1]; 93 ((sortn))[j+1]=tempname; 94 (sortc)[j+1]=tempcount; 95 } 96 } 97 } 98 System.out.println("输出出现次数最高的10个单词:"); 99 for(i=0;i<10;i++) 100 { 101 System.out.println((sortn)[i].toString()+" "+" "+(sortc)[i]); 102 } 103 } 104 } 105 }
最后总结本次的个人项目:
在周四得知题目后,大致的将思路及方法理了一次。在有方法的前提下预估了本次实验完成时间为0.5人日,即4-6个小时的时间。但周六实际操作中也遇到问题,在解决问题上花费的时间很多,到周日上午才基本完成。在单词出现次数的统计这一块顺利完成,而排序是一个卡壳的地方。在想好用数组将treemap中的数据“导出”后,便确定了用冒泡排序法来进行排序。但问题恰恰出现在“导出”上。其实这里的“导出”就是将treemap中的<String,Integer>两种数据类型放置到String[]、int[]两个数组中。但出现nullpointerException的异常(空指针异常)就是在数组的初始化上出现了问题,因为我直接是这样定义的:String[] sortn=null; int[] sortc=null。其实应当要赋给一个确定的长度值。int[] sortc=new int[20];这样的才正确。为了不浪费空间及提高效率,我在单词统计之前就将不重复单词个数cd统计出来,这样就可以不浪费数组空间并能提高效率了。
不过程序还存在明显的缺陷,即单词的判断上会出现差错(当符号与单词紧邻时无法正确的“剥离”出单词来)。
因此程序需要不断的检查,使其变得更好,正确完整的预计时间是很好解决问题的一个方法。