软工网络16作业2
1、码云项目地址:
https://gitee.com/eshy/PersonalProject-Java
2、个人的PSP表格:
PSP2.1 | 个人开发流程 | 预估耗费时间(分钟) | 实际耗费时间 |
---|---|---|---|
Planning | 计划 | 35 | 40 |
· Estimate | 明确需求和其他相关因素,估计每个阶段的时间成本 | 30 | 45 |
Development | 开发 | 500 | 530 |
· Analysis | 需求分析 (包括学习新技术) | 120 | 145 |
· Design Spec | 生成设计文档 | 30 | 50 |
· Design Review | 设计复审 | 100 | 120 |
· Coding Standard | 代码规范 | 30 | 45 |
· Design | 具体设计 | 30 | 30 |
· Coding | 具体编码 | 100 | 130 |
· Code Review | 代码复审 | 30 | 40 |
· Test | 测试(自我测试,修改代码,提交修改) | 30 | 50 |
Reporting | 报告 | 70 | 80 |
· | 测试报告 | 30 | 45 |
· | 计算工作量 | 30 | 40 |
· | 并提出过程改进计划 | 30 | 40 |
3、解题思路描述:
首先我考虑的是从文件取出来字符串,再将字符串的单词、分隔符一个个取出来,然后用hashmap储存单词(分隔符),其中key值为单词(分隔符),value值为其数量。
统计单词的数量只需要将hashmap中的单词部分取出来,然后将value部分相加。统计分隔符同理。
然后行数的统计是通过取文件中的单词时利用的是readLine()
函数,所以没使用一次就让行计数器加一就行了。
因为刚接触了不久的java,所以相较c++会更熟悉一些,但是还是有很多的函数不熟悉,就比如说文件流我不是很会用,就是通过百度,然后慢慢看它的定义再使用,我大部分的时间都花在了这个上面。
4、设计实现过程:
- LineCounter()函数:实现有效行统计。
- CharacterCounter()函数:实现字符统计。
- WordCounter()函数:实现单词统计。
- WordSort()函数:将出现频率最高的十个单词放在一个链表中。
- sortMap()函数:对单词按词频排序,词频相同按字典方式排序。
5、代码说明:
1、LineCounter()函数
public static int LineCounter(String path) throws Exception {//有效行计算
InputStreamReader is1 = new InputStreamReader(new FileInputStream(path));
BufferedReader br1 = new BufferedReader(is1);
String str = br1.readLine();
int lines = 0;
while(str!=null) {
if(!str.equals(""))
lines++;
str = br1.readLine();
}
br1.close();
is1.close();
return lines;
}
有效行统计函数,我使用的方法就是将文件打开一次,然后逐行读取,只要不为空,就让有效行加1。
2、WordCounter()函数
public static int WordCounter(Map<String,Integer> map) throws Exception{//单词数计算
int words = 0;
Set<String> set = map.keySet();
for(String s:set) {
if(s.charAt(0)>='a'&&s.charAt(0)<='z')
words += map.get(s);
}
return words;
}
单词统计函数,将map中的单词取出来,然后让他们的value值相加。
3、WordSort()函数
public static String WordSort(Map<String,Integer> map) throws Exception{
List<Map.Entry<String, Integer>> l = sortMap(map);
String[] st = new String[l.size()];
String file = new String();
int i = 0;
for(Map.Entry<String, Integer> k : l) {
if(k.getKey().charAt(0)>='a'&&k.getKey().charAt(0)<='z') {
st[i] = "<" + k.getKey() + ">:" + k.getValue();
i++;
if(i>=10)
break;
}
}
for(i = 0;i < 10;i++) {
file = file+"\r\n"+st[i];
}
return file;
}
词频前十单词统计,将map用sortMap函数进行排序,然后直接取出前十个单词。
4、sortMap()函数
public static List sortMap(Map map) { // 对单词词频的Map进行排序
List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if (o1.getValue() == o2.getValue()) {
return o1.getKey().compareTo(o2.getKey());//词频相同时,按字典排列
}
return o2.getValue() - o1.getValue(); //降序排列
}
});
return list;
}
单词词频排序函数。
6、单元测试
1、输入文件和输出文件展示:
2、Junit测试:
7、个人总结
我个人的习惯就是看到题目之后就直接顺着打代码,走一步是一步,导致了我走了很多弯路,经常推翻之前写的一些函数,费了不少的时间,打代码的过程很痛苦。所以我就试着先理出流程,然后再顺着流程编写代码,虽然不是很熟练,但是相比较没有理流程轻松了不少。我觉得接下来的编程任务整理流程这一步真的很重要,我会慢慢适应这个方式。