根据实验二 软件工程我的项目的要求本次软件项目的需求有如下几点:
1.程序可读入任意英文文本文件,该文件中英文词数大于等于1个,程序须要很壮健,能读取容纳英文原版《哈利波特》10万词以上的文章。
2.指定单词词频统计功能:用户可输入从该文本中想要查找词频的一个或任意多个英文单词,运行程序的统计功能可显示对应单词在文本中出现的次数和柱状图。
3.高频词统计功能:用户从键盘输入高频词输出的个数k,运行程序统计功能,可按文本中词频数降序显示前k个单词的词频及单词。
4.统计该文本全部单词数量及词频数,并能将单词及词频数按字典顺序输出到文件result.txt。html
1.对于需求一、需求4须要有读入文本数据、向文本输出数据的功能。
2.对于需求3和需求4须要有排序的功能
3.整个项目要求有对词频进行统计的功能java
1.本次项目有两个类:
(1)main.java主要实现文本读入和功能选择的功能,根据用户输入的选择调用function.java中相应的功能函数。
(2)function.java实现排序(sort函数),查找单词词频显示柱状图(find函数),输出前n个高频词(print函数),单词及词频数按字典顺序输出到文件result.txt(Sort函数)四个主要功能。
2.数据结构:
本次项目采用TreeMap存储从文本读入的数据,用LinkedList进行词频排序。
3.流程图:
本项目总的流程图为:
git
1.显示单词词频和柱状图
github
2.输出前K个高频词
数组
3.向result.txt写入单词和词频
数据结构
1.文件读入并统计词频模块化
// 读取要处理的文件 BufferedReader b = new BufferedReader(new FileReader("src/HarryPotter.txt")); //<单词:词频> Map<String, Integer> map = new TreeMap<String, Integer>(); String value= b.readLine(); while (value!= null) { //处理标点符号 String[] words = value.split("[【】、.。,\"!--;:?\'\\] ]"); for (int i = 0; i < words.length; i++) { //将大写字母转换为小写字母 String key = words[i].toLowerCase(); if (key.length() > 0) { if (!map.containsKey(key)) { map.put(key, 1); } else { int k = map.get(key)+1;// 若是不是第一次出现,就把k值++ map.put(key, k); } } } value = b.readLine(); }
2.按词频或字母排序函数
Set<Entry<String,Integer>> m= map.entrySet(); LinkedList<Entry<String, Integer>> List = new LinkedList<Entry<String,Integer>>(m); //按值排序 if(a==2) { Collections.sort(List, new Comparator<Entry<String,Integer>>() { public int compare(Entry<String, Integer> a, Entry<String, Integer> b) { return b.getValue().compareTo(a.getValue()); } }); //按键排序 else if(a==3) { Collections.sort(List, new Comparator<Entry<String,Integer>>() { public int compare(Entry<String, Integer> a, Entry<String, Integer> b) { return a.getKey().compareTo(b.getKey()); } }); } //排序后存入Map中 for(Entry<String,Integer> entry: List) { Map.put(entry.getKey(), entry.getValue()); } }
3.向文件写入单词词频测试
//建立文件 File file = new File("result.txt"); //向文件写入 FileWriter f = new FileWriter(file.getAbsoluteFile()); for(Entry<String,Integer> w: Map.entrySet()) { f.write(w.getKey() + "/" + w.getValue()+" "); } f.close(); System.out.println("结束!");
1.本次项目中各功能在function类中,用函数实现各个功能,经过用户输值调用相应的功能,以此来实现模块化。
2.在刚开始设计读入文件数据的时候,打算采用二维数组存放单词,相应的一维数组存放个数,但发现数组太大,并且在进行排序的时候不方便所以采用了<键:值>的映射存放数据。
3.在进行柱状图绘制时,因为除以500后的小数没法表示,只能表示出大概的趋势。编码
任务内容 | 计划完成时间(min) | 实际完成时间(min) |
---|---|---|
计划 | 5 | 3 |
规划工做步骤 | 10 | 7 |
开发 | 173 | 202 |
需求分析 | 10 | 15 |
生成文档 | 5 | 10 |
设计复审 | 3 | 2 |
代码规范 | 20 | 15 |
具体编码 | 100 | 120 |
代码复审 | 10 | 5 |
测试 | 25 | 40 |
报告 | 15 | 12 |
测试报告 | 5 | 7 |
计算报告量 | 5 | 2 |
过后总结 | 5 | 3 |
从表中能够看出在编码阶段时间较多且和本身估计的时间差距较大,主要是在进行数据结构的选择上错误,浪费大量时间进行修改,而且因为长时间没有使用Java,全部有些生疏,在测试阶段时间也比较长,本身开始的逻辑上有些混乱致使结果不正确显示,一步步的调试最终实现了相应功能。
点击源码可查看项目源代码