2018软工实践第二次作业

软工实践第二次作业

一、GitHub地址

二、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 1250 2020
· Estimate · 估计这个任务需要多少时间 1250 2020
Development 开发 1200 1880
· Analysis · 需求分析 (包括学习新技术) 360 600
· Design Spec · 生成设计文档 10 30
· Design Review · 设计复审 10 20
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 30
· Design · 具体设计 180 120
· Coding · 具体编码 480 720
· Code Review · 代码复审 30 120
· Test · 测试(自我测试,修改代码,提交修改) 120 240
Reporting 报告 50 140
· Test Repor · 测试报告 30 90
· Size Measurement · 计算工作量 10 20
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 10 30
|       |   合计  |1250 |2020  

三、解题思路描述

按照题目的要求,统计input.txt中的以下几个指标

  • 统计文件的字符数:
    只需要统计Ascii码,汉字不需考虑
    空格,水平制表符,换行符,均算字符
  • 统计文件的单词总数,单词:至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。
    英文字母: A-Z,a-z
    字母数字符号:A-Z, a-z,0-9
    分割符:空格,非字母数字符号
    例:file123是一个单词, 123file不是一个单词。file,File和FILE是同一个单词
  • 统计文件的有效行数:任何包含非空白字符的行,都需要统计。
  • 统计文件中各单词的出现次数,最终只输出频率最高的10个。频率相同的单词,优先输出字典序靠前的单词。
  • 按照字典序输出到文件result.txt:例如,windows95,windows98和windows2000同时出现时,则先输出windows2000
  • 输出的单词统一为小写格式

1.统计行数

由于只需要统计包含非空白字符的行,所以空白行可以忽略不计。我采用的方法的是逐行读取,读到非空白字符则行数加一;

2.统计字符数

由于题目要求只需要统计Ascii码,汉字不需考虑,所以我去学习了正则表达式,使用正则表达式判断字符是否满足要求,满足则字符数加一;

3.统计单词数,输出频率最高的十个

题目对有效单词的要求是至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。一开始我是先分割字符串,然后使用正则表达式判断,但是之后注意到题目中对分隔符的定义是空格和非字母数字符号。所以像汉字这样的字符也需要当作分隔符,我在分割字符串前先对整个字符串进行遍历,将非字母数字符号替换成空格,再进行分割,然后通过正则判断并统计单词个数。将得到的单词进行小写转换后存入一个HashMap<String, Integer>类型的变量map,并在存入时更新该单词的频率;

4.将结果输出到result.txt

使用System.setOut()输出到目标文件;

5.查找的资料

这次使用的是之前没学过的JAVA,所以很多东西都需要现学现用,主要是翻阅《Java 从入门到精通》来进行学习,在网上也查找了正则表达式的使用,BufferedReader和HashMap<String, Integer>等等的资料。

四、设计实现过程

结构设计图

image

单元测试

       1.空白文本

       2.错误文件名

       3.多个输入参数

       4.包含相同单词(如abcd和ABCD)

       5.超过十个合法单词

       6.包含非空白字符但无有效单词

       7.全部为空白字符

       8.包含汉字的文本

       9.全部为有效单词的文本

       10.单词长度全部小于4的文本

单元测试结果如下

image

单元测试覆盖率如图所示

image

五、性能分析

image

image

测试的时候循环运行了100000次,一共用了86.014s,
可以看出最耗时间的是java.io.PrintStream以及java.io.FileOutputStream,
分别占用了35.8%和16.6%的时间,在IO方面花费的时间是最多的;下面是对内存使用的分析

image

六、部分代码说明

CharacterCount.java 统计字符数

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CharacterCount {
    public int charCount(String string) throws IOException {
        int characters = 0;
        String regex = "\\p{ASCII}";  //正则表达式判断字符是否合法
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(string);
        while (matcher.find()) {
            characters++;  //统计字符数
        }
        return characters - 1;
    }
}  

most.java 输出十个词频最高的单词

import java.util.*;
public class most {
    public List<Map.Entry<String, Integer>> mostWord(HashMap<String, Integer> map) {
        // 将HashMap类型转换为list类型
        List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
        //对单词进行排序
        list.sort(new MapComparator());
        if (list.size() < 10) {
            return list.subList(0, list.size());
        }
        else {
            return list.subList(0, 10);
        }
    }
    
    private class MapComparator implements Comparator<Map.Entry<String, Integer>> {
        public int compare(Map.Entry<String, Integer> word1, Map.Entry<String, Integer> word2) {
        //词频不等则按词频排序
        //相等则按字典序排序
            if (word1.getValue().compareTo(word2.getValue()) != 0) {
                return word2.getValue().compareTo(word1.getValue());
            }
            else {
                return word1.getKey().compareTo(word2.getKey());
            }
        }
    }
}    

由于刚开始学习Java,对Java的使用还不太熟悉,有部分代码借鉴于:https://github.com/Dark-Existed

异常处理

无输入参数时,输出"Error: No input file name!";
输入参数有多个时,输出"Error: Please enter one file name!";

String path = "";
        if (args == null) {
            System.out.println("Error: No input file name!");
        }
        else if (args.length > 1) {
            System.out.println("Error: Please enter one file name!");
        }
        else {
            path = args[0];
        }  

七、总结和感想

  • 这次的作业用的是Java来写的,做之前有在C++ 还有Java之间纠结过到底用哪种语言,Java对于我有点陌生,但是考虑到C++ 虽然学过,但自己使用的不多,还不如给自己点压力用Java来完成。过程还是挺的不容易,一开始两眼一抹黑都不知道从何做起,自己一边学一边实现,不会的上网百度查找资料,多亏了舍友志炜大佬在旁指导我,给予我一些提示和帮助最终才完成了这个任务。虽然完成的挺不容易,但是之中还是学到了不少,懂得了Java的一点使用方法,懂得了代码封装,也懂得了《构建之法》中所说的一个项目的完成并不是简简单单地敲完代码就完成了,还包括了需求分析,单元测试,异常处理等等。这次的个人项目对于我来说是一个很大的挑战,虽然作业完成的或许还不够好,存在着或多或少的缺陷,但是我觉得我这次的收获已经蛮多了,自己的学习之路还有很长,接下来的日子继续努力吧!
posted @ 2018-09-11 22:29  yao正义  阅读(330)  评论(3编辑  收藏  举报