201621123053 张雨阳软工作业2
1.码云项目地址
https://gitee.com/milan_kaka/2018_soft_work/tree/master
2.PSP表格
PSP2.1 | 个人开发流程 | 预估耗费时间(分钟) | 实际耗费时间(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 50 |
· Estimate | 明确需求和其他相关因素,估计每个阶段的时间成本 | 20 | 40 |
Development | 开发 | 300 | 780 |
· Analysis | 需求分析 (包括学习新技术) | 60 | 120 |
· Design Spec | 生成设计文档 | 30 | 60 |
· Design Review | 设计复审 | 30 | 60 |
· Coding Standard | 代码规范 | 15 | 20 |
· Design | 具体设计 | 120 | 150 |
· Coding | 具体编码 | 180 | 200 |
· Code Review | 代码复审 | 30 | 40 |
· Test | 测试(自我测试,修改代码,提交修改) | 100 | 120 |
Reporting | 报告 | 60 | 60 |
· | 测试报告 | 30 | 100 |
· | 计算工作量 | 20 | 20 |
· | 并提出过程改进计划 | 20 | 20 |
3.解题思路描述
题目要求实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。思路如下
- 以字符串形式读入文件数据,统计字符串的字符数。由于要求中空格,水平制表符,换行符,均算字符,所以对原始数据不需要做修改。(字符数)
- 通过分隔符(空格,换行等),再将一个大的字符串分成小的字符串,存放在数组中。根据单词构成,统计数组中满足相应条件的元素个数。(单词数)
- 通过换行符将大字符串分割,放入数组中。计算数组大小。(行数)
- 拓展功能
4.设计实现过程
建三个类,分别是WordCounter类(统计方法),FileDeal(文件处理)和Main(主函数)。
WordCounter类中主要方法如下
- public int getCharCount() //统计字符个数,按ASCⅡ码来统计
- public int getWordCount() // 统计单词总数
- public Map getWordFreq() // 统计单词个数
- public int getLineCount() // 统计有效行数
FileDeal类中主要方法如下
- public String FileToString(String path) throws IOException // 读取文件数据并转化成字符串
- public void WriteToFile(String str) throws IOException // 将结果写入文件
Main函数主调用前面两个类的方法,实现程序功能。
5.代码说明
(1). 统计字符个数 public int getCharCount()
public int getCharCount() //统计字符个数,按ASCⅡ码来统计
{
char a;
for (int i = 0; i < text.length(); i++) {
a = text.charAt(i);
if (a >= 48 && a <= 57 ||a >= 65 && a <= 90 ||a >= 97 && a <= 122) {
charNum++;
}
}
return charNum;
}
将text中的字符单独取出放到a中,若a中字符符合规范,则charnum+1,否则继续遍历text直到结束。
(2). 统计单词总数 public int getWordCount()
public int getWordCount() // 统计单词总数(注意单词是以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。)
{
String t = text;
String[] Word = t.split("\\s"); // 对字符串进行分词操作(注意\\s)
for (int i = 0; i < Word.length; i++) {
if (Word[i].length() < 4) { // 判断长度是否大于等于4
continue;
} else {
int flag = 1; // 判断字符串的前四位是否是英文字母
char a;
for (int j = 0; j < 4; j++) {
a = Word[i].charAt(j);
if (!(a >= 'A' && a <= 'Z' || a >= 'a' && a <= 'z')) {
flag = 0;
}
}
if (flag == 1) {
wordCount++;
}
}
}
return wordCount;
}
先将text进行分词操作。用到split("\s")方法。再判断字符串是否符合单词要求(单词:以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。) 如果符合,wordCount+1,否则继续遍历直到结束。
(3). 统计单词个数 public Map getWordFreq()
public Map getWordFreq() // 统计单词个数
{
wordFreq = new HashMap<String, Integer>();
String t = text;
String[] Word = t.split("\\s");
for (int i = 0; i < Word.length; i++) {
if (Word[i].length() < 4) {
continue;
} else {
int flag = 1;
char a;
for (int j = 0; j < 4; j++) {
a = Word[i].charAt(j);
if (!(a >= 'A' && a <= 'Z' || a >= 'a' && a <= 'z')) {
flag = 0;
}
}
if (flag == 1) {
Word[i] = Word[i].trim().toLowerCase(); // 将字符串转化为小写
if (wordFreq.get(Word[i]) == null) { // 判断之前Map中是否出现过该字符串
wordFreq.put(Word[i], 1);
} else
wordFreq.put(Word[i], wordFreq.get(Word[i]) + 1);
}
}
}
return wordFreq;
}
开始的操作和上一个方法相似,找出符合单词描述的字符串,存放到Map中,若没存过就记为1,若存过+1。
(4). 统计有效行数 public int getLineCount()
public int getLineCount() { // 统计有效行数
String[] line = text.split("\r\n");=
for (int i = 0; i < line.length; i++) {
if (line[i].trim().length() == 0)
continue;
LineCount = LineCount + 1;
}
return LineCount;
}
以行为单位分割text,之后检验是否有只含空格或换行的无效行。若不是无效行+1。
6.单元测试
对于单元测试还是没有完全的理解。不知道怎么去编写测试代码。在询问和借鉴了别的同学后还是有问题。
7.效能分析
JProfiler安装后全英文有些看不懂。。
8.实验总结
- 这次是第一个软件工程的实践作业,在构思和实际写代码上遇到了很多的困难。主要是自己Java掌握的不够完善。询问了很多同学,自己也查询了很多资料最后勉强完成了这个程序。自己Java方面问题主要是没有面向对象的思想以及Map等类运用的不够好。总是希望可以回避复杂的数据结构从而导致了自己浪费了很多的时间。
- 关于软件工程的单元测试与性能分析,自己掌握的确实很差。单元测试代码不知道怎么去实现。参考了同学的代码也无法正确的进行。而效能分析的软件更是无从下手。自己课后还得继续的钻研才能更好的学习这门课程。