个人软件开发过程
上周四(2014年2月20号)软件工程的课上,老师给推荐了这个博客,感觉真的是一个很不错的博客,可以记录自己的编程记录,同时也能够发表出去,供行业牛人批评指正。文章正式开始前,先表示一下对王老师的谢意。
这次课上,老师留了这学期的第一个个人作业:写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的10个词打印出来。这个程序一给出来,很自然的我就想到了用java进行编写,而且大概的思路已经有了,因为之前做编译实验的时候做过类似的文件处理的操作。心里还暗自高兴了一下,心想这个程序这么简单,不出两个小时就搞定。
到周五的晚上,准备开始做这个题目,20:30,拿着电脑到了自习室,打开电脑之后,聊了会qq,马上21:00,同学提醒我还得开会,差点忘了,这叫中断吗?应该不算吧,因为一直都没有开始呢。。。开完会回来大概21:20,这个可真得开始了:
这个程序我大概的思路是这样的:1.首先完成读文件的操作,然后能够把文件的内容打印出来。
2.然后,把读出来的内容,分成单词。
3.分割成单词了就开始统计单词出现的个数,所有的都统计完,把出现频率最高的10个单词打印出来即可。
按照这个思路,打开myeclipse,寻找以前的文件处理的代码(这是不是叫代码重用啊!!!),很快就完成了读文件的操作,代码如下:
BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); System.out.print("请输入文件的路径:"); try { fileLoad=in.readLine(); } catch (IOException e) { e.printStackTrace(); } try { FileReader fr = new FileReader(fileLoad); BufferedReader br=new BufferedReader(fr); String cont=br.readLine(); } catch (FileNotFoundException e) { e.printStackTrace(); }
然后开始对读出来的字符串做处理,分成一个个的单词,对一个英文句子来说,空格是首先要考虑的:String allWord[]=cont.split(" ");
做到这,大概20分钟,就收拾东西回宿舍了,刚刚开学,一时还没有那么用功。
周六,也就是2014年2月22日,上午起来吃了饭,9:00开始完善自己的程序,应该不能说完善,因为本来都没有完成呢。首先要完成的功能是统计单词出现的次数。这里我用了两个集合类,第一个是把分割的所有的单词存放到一个名为list的集合类中,然后在单词存放到listNotRepeat集合类中,listNotRepeat中的单词不能重复。仔细研究了一下英文文章,分割单词时还要考虑‘;’,‘,’等等之类的:把单词加入到两个集合类中的代码如下:
/* * 读取文本文件的内容,并将文本文件的内容单词出现的次数 * 存入到两个集合类list和listNotRepeat中,list中存放着 * 文本文件中出现的所有的单词,有重复的;listNotRepeat中也存放着 * 文本文件中出现的单词,没有重复的。 */ public void addWordToList(BufferedReader br) { String cont; try { cont=br.readLine(); while(cont!=null) { String allWord[]=cont.split(" |,"); for (int i=0;i<allWord.length;i++) { if(allWord[i].length()>0)//文章中可能存在两个单词之间有两个或更多个空格,去除空格 { if(allWord[i].contains(".")||allWord[i].contains(";")) { String subStringWord[]=allWord[i].split("\\.|;"); for(int j=0;j<subStringWord.length;j++) { if(!listNotRepeat.contains(subStringWord[j])) { listNotRepeat.add(subStringWord[j]); } list.add(subStringWord[j]); } } else { if(!listNotRepeat.contains(allWord[i])) { listNotRepeat.add(allWord[i]); } list.add(allWord[i]); } } } cont=br.readLine(); } } catch (IOException e) { e.printStackTrace(); } }
然后根据两个集合算出单词出现的次数,并把每个单词对应出现的次数以一个javabean的对象的形式存放到另一个集合类wordList中,以便打印出现频率最高的前十个单词使用。
for(int i=0;i<listNotRepeat.size();i++)//将每个单词出现的次数计算出来 { int a=Collections.frequency(list,listNotRepeat.get(i)); wordList.add(new Word((String) listNotRepeat.get(i),a)); }
这里面出现的Word类的定义是这样的:
package cn.stdu.edu.domain; public class Word { private String wordName; private int time; public String getWordName() { return wordName; } public void setWordName(String wordName) { this.wordName = wordName; } public int getTime() { return time; } public void setTime(int time) { this.time = time; } public Word(String wordName,int time) { this.wordName=wordName; this.time=time; } }
到这,本来想的马上就做完了,因为只剩下把出现频率最高的打印出来。就先休息了一下(这应该叫中断吧 哈~~zz).
休息完了,回来开始动手写代码,╮(╯▽╰)╭,不知道怎么写了,想排序吧,但是不知道怎么排,集合类里面也没有相关的方法,因为涉及到键值对,这里难住了。。。通过查资料什么的,最后确定下来了一种方法,就是前面用到了word对象的集合类wordList。我的思路是,遍历10次,每一次找到出现次数最大的那个对象,然后记录这个对象在wordList集合类中的索引值,然后打印出相应的单词和在文章中出现的次数,再把它从集合类中删除掉。代码如下:
/** * 打印出现频率最高的前10个单词 */ int max=0; int n=0; //记录次数出现最多的单词对象在几何对象中的索引值 System.out.println("单词出现频率最高的10个单词:"); System.out.println("单词\t\t\t次数"); for(int j=0;j<10;j++) { for(int i=0;i<wordList.size();i++) { if(max<wordList.get(i).getTime()) { max=wordList.get(i).getTime(); n=i; } } System.out.println(wordList.get(n).getWordName()+"\t\t\t"+max); wordList.remove(n); n=0; max=0; }
到这为止,这个程序似乎是做完了。也能够输出正确的结果了,但是作为这个程序的开发者,我肯定知道这个输入路径的时候只能输入什么,但是如果它作为一个软件交给用户的时候,用户肯定有输入错误的时候,那么如果输入错误,会出现什么呢?结果出现了下面的结果:
这些东西给我自己看是重要的参考信息,但是要是作为一个项目的话,让用看到了这样的东东,后果恐怕很严重啊。所以这个异常必须处理,我的处理思路是如果用户输入的路径不对,应给出相应的提示,三次输入机会,3次之后还是没有输入正确的路径,程序自动退出。代码如下:
int cishu=0; while(cishu<=3) { System.out.print("请输入文件的路径:"); try { fileLoad=in.readLine(); } catch (IOException e) { e.printStackTrace(); } try { FileReader fr = new FileReader(fileLoad); BufferedReader br=new BufferedReader(fr); readAndPrint.addWordToList(br);//这里是调用的addWordList方法,就是前面提到的list和listNotRepeat集合类的赋值 readAndPrint.printWord(); //这个方法的功能是查找单词出现的次数,并打印出出现频率最高的前10个单词 cishu=4; } catch (FileNotFoundException e) { System.out.println("未找到相应文件,请检查路径输入是否正确!"); if(3==cishu) { System.out.println("\n程序退出,谢谢使用!"); } else { System.out.println("\n还有"+(3-cishu)+"次机会"); } }finally { cishu++; } }
结果显示如下:
这次这个结果就挺令人满意了,相信用户看到这个,也只能怨自己输入的不正确了。 到这这个程序就算完成了,一直弄到12点,中间夹带着中断了一会,洗了洗衣服。
程序中出现的问题: 统计次数; 解决方案:先是想到了一种自己的解决方案,但是太过啰嗦,影响效率,通过搜集资料,查到了相应的方法,解决了该问题
排序; 解决方案:想通过数组排序来解决,这样也可以。但是想到了直接找出现次数最多的那个单词实现起来更方便一点,如此就解决了
以上是我整个编写程序的过程,不足之处请大家指明,并提出自己宝贵的意见,谢谢。