201671030122杨凡亿 实验二 词频统计软件项目报告
项目 | 内容 |
---|---|
课程名称 | 2016级计算机科学与工程学院软件工程(西北师范大学) |
作业要求 | 实验三 软件工程个人项目 |
作业目的 | 1.掌握软件项目个人开发流程 2.掌握Github上发布软件项目的操作方法 |
一.需求分析
- 程序可读入任意英文文本文件,即用户需要自己输入文件名。
- 程序需要很壮健,能读取容纳英文原版《哈利波特》10万词以上的文章,即数据的存储方式。
- 指定单词词频统计功能,即(1)用户可输入一个或多个单词查询对应的词频(2)并显示对应的柱状图。
- 高频词统计功能:用户从键盘输入高频词输出的个数k,运行程序统计功能,可按文本中词频数降序显示前k个单词的词频及单词。
- 统计该文本所有单词数量及词频数,并能将单词及词频数按字典顺序输出到文件result.txt。
二.功能设计
- 菜单功能。列出用户可以操作的命令。对于用户输入的无效命令应该有相应的错误处理能力。
- 文件的输入和输出功能。在文件输入时,若文件不存,则应有相应的错误处理功能。
- 词频统计功能。
- 排序功能。按值排序,按键排序。
- 显示功能。(1)显示指定单词的词频和柱状图,若用户输入无效单词,应该有相应提示。(2)高频词的统计功能。
三.设计实现
(1)程序共有两个类。
- Main.java是主类。主要利用switch结构对用户输入的命令进行判断,并调用相应的函数。
- function.java 主要是一些功能方法。包括:文件的读入(input)、菜单显示(menu)、指定单词词频统计(frequency)、排序(rank)、高频词统计(Highwordcount)、输出到文件result.txt(output)
- 程序执行时,主要是在主类Main.java里面调用function.java类里面的方法,实现需要的功能。
(2)数据结构:用HashMap<String, Integer>存储分词后的单词和对应的词频。
(3)总体流程图
四.测试运行
-
文件的读入
-
高频词统计
-
指定单词词频统计
-
输入到result.txt
-
一些错误处理
五.部分代码
-
文件读入并统计词频
try {
FileInputStream fis = new FileInputStream(filename);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String temp="";
String info="";
while((temp = br.readLine())!=null)
{
String[] str = temp.split("([^a-zA-Z])"); //过滤出只含有字母的
for(int i=0;i<str.length;i++)
{
String word = str[i].trim();
if(word.length()!=0) //去除长度为0的行
staff.put(word, staff.getOrDefault(word, 0)+1);
}
}
br.close();
rank();//按值排序
System.out.println("文件读入成功!请继续...");
}catch(Exception e) {
System.out.println("文件不存在!!!请重新确认!");
}
-
文件输出到result.txt
Set<Entry<String,Integer>> mapEntries = staff.entrySet();//该方法将键和值的映射关系作为对象存储到了Set集合中
List<Entry<String,Integer>> aList1 = new ArrayList<Entry<String,Integer>>(mapEntries);
//按字典序排序
Collections.sort(aList1, new Comparator<Entry<String,Integer>>() {
@Override
public int compare(Entry<String, Integer> ele1,
Entry<String, Integer> ele2) {
return ele1.getKey().compareTo(ele2.getKey());
}
});
PrintWriter out = null;
try {
out = new PrintWriter("result.txt");
out.println("total: "+aList.size()); //输出总词数
for(Entry<String,Integer> entry: aList1)
{
out.println(entry.getKey()+"\t"+entry.getValue());
}
} catch (FileNotFoundException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
out.close();
System.out.println("已写到result.txt 请继续...");
}
六.总结
- 每个功能的实现都在function类中,在主类里面通过类名直接调用相应的方法实现功能,以此实现模块化。
- 在画柱状图时,本想采用重写paint()方法来实现,也参考了网上的一些代码,但由于自己知识有限,没能实现。后面会继续完善。
- 对于需求分析和设计,应当重视。在此次设计中,由于没有做好这些,在编码完成测试时才发现一些功能和需求不同,又花了一点时间修改。这要是在大项目中有点不可想象。
七.PSP
PSP | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 8 | 5 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 8 | 5 |
Development | 开发 | 170 | 220 |
Analysis | 需求分析(包括学习新技术) | 20 | 15 |
Design Spec | 生成设计文档 | 10 | 12 |
Design Review | 设计复审 | 11 | 13 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 5 | 9 |
Design | 具体设计 | 10 | 12 |
Coding | 具体编码 | 70 | 130 |
Code Review | 代码复审 | 10 | 15 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 60 |
Reporting | 报告 | 15 | 20 |
Test Report | 测试报告 | 6 | 9 |
Size Measurement | 计算工作量 | 5 | 3 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 5 | 4 |
- 从表中可以看到,在编码和测试部分花费了很长是的时间,和预期的是计划差距有点大。主要是对于需求没有弄得很清楚,导致在测试阶段根据测试结果又修改代码,浪费了很时间;其次是很久没有用到java,在编码时又化了很多时间看书。我之前一直对需求分析和设计不是很重视,但通过这次小项目,我想对于需求分析和设计等有了更深的体会和感受,在接下来的学习中,会按照软件开发流程完成学习任务。