软件质量与测试第二周作业WordCount

时间:2022-06-13 19:07:31

GitHub地址:https://github.com/MrZYF/WordCount

一、PSP表格

PSP2.1

PSP阶段

预估耗时

(分钟)

实际耗时

(分钟)

Planning

计划

10 10

· Estimate

· 估计这个任务需要多少时间

10 10

Development

开发

520 760

· Analysis

· 需求分析 (包括学习新技术)

30 30

· Design Spec

· 生成设计文档

- -

· Design Review

· 设计复审 (和同事审核设计文档)

- -

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

10 10

· Design

· 具体设计

60 100

· Coding

· 具体编码

300 500

· Code Review

· 代码复审

60 60

· Test

· 测试(自我测试,修改代码,提交修改)

60 60

Reporting

报告

120 110

· Test Report

· 测试报告

60 60

· Size Measurement

· 计算工作量

30 20

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

30 30
 

合计

650 880

 

二、解题思路

1、该程序要求在控制台输入参数后运行,所以编程时将输入的参数存入args[]中进行逐个判断。

2、作业要求对指定文本内的字符数、单词总数和行数进行统计,且可指定输出至文件,以及一些其它扩展内容。输入的指令不要求顺序,但输出的文本要按照一定的顺序输出。所以可以将每个指令设成一个布尔值,检测完所有指令后按顺序计算并输出。

3、将文本内容读取进String中,对该字符串进行检测则可得出结果。

4、通过文件夹的递归遍历路径下的所有地址,匹配所有满足要求的文本。

5、统计单词个数时,与停用词表中的单词逐个比较,若相同则不计数。

6、注释行、空行、代码行的判断通过正则表达式判断。

三、程序设计实现过程

private static void argsProcessing(String[] args) 参数的判断和处理函数

private static void createNewFile(String path) 创建新文件的函数

private static void lineType(String line) 判断行的类型(代码行、空行或注释行)的函数

private static String getFileContent(File file) throws IOException 读取文件内容的函数

public static void output(String inputPath, PrintWriter output) throws IOException 输出函数

public static void outputAllFiles(File file, PrintWriter output) 遍历所有满足要求的文件并输出的函数

public static void main(String[] args) throws IOException 主函数

四、代码说明

    // 参数处理
    private static void argsProcessing(String[] args) {
        if (args.length == 0) {
            System.out.println("Please input parameters!");
            return;
        }
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
            case "-c":
                c = true;
                break;
            case "-w":
                w = true;
                break;
            case "-l":
                l = true;
                break;
            case "-o":
                o = true;
                i++;
                outputPath = args[i];
                break;
            case "-s":
                s = true;
                break;
            case "-a":
                a = true;
                break;
            case "-e":
                e = true;
                i++;
                stopListPath = args[i];
                break;
            default:
                inputPath = args[i];
                break;
            }
        }
        if (inputPath == null) {
            System.out.println("Please input the input_file_name");
            return;
        }
    }
    // 判断一行为代码行、空行还是注释行
    private static void lineType(String line) {
        if (comment) {
            // ...*/的情况
            if (line.matches("[\\s\\S]*\\*/[\\s\\S]*")) {
                comment = false;
                if (line.matches("[\\s\\S]*\\*/\\s*")) {
                    commentLine++;
                } else {
                    codeLine++;
                }
                return;
            }
            commentLine++;
            return;
        }
        // 空行
        if (line.matches("\\s*\\S?\\s*")) {
            blankLine++;
            return;
        }
        // //...和/*...*/的情况
        if (line.matches("\\s*\\S?\\s*//[\\s\\S]*") || line.matches("\\s*\\S?\\s*/\\*[\\s\\S]*\\*/\\s*")) {
            commentLine++;
            return;
        }
        // /*...的情况
        if (line.matches("\\s*\\S?\\s*/\\*[\\s\\S]*")) {
            commentLine++;
            comment = true;
            return;
        }
        codeLine++;
    }
    // 读文件内容
    private static String getFileContent(File file) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(file));
        String line = "";
        String content = "";
        // 一次读入一行,直到读入null为文件结束
        if ((line = reader.readLine()) != null) {
            content = line;
            lineNumber++;
            lineType(line);
        }
        while ((line = reader.readLine()) != null) {
            content = content + "\n" + line;
            lineNumber++;
            lineType(line);
        }
        reader.close();
        comment = false;
        return content;
    }

统计单词总数:

        if (w) {
            String[] words = content.split(",| |\n|\t"); // 单词分隔符
            int number = 0;
            for (int i = 0; i < words.length; i++) {
                // 单词计数,排除双分隔符产生的空字符串
                if (!(words[i].equals("") || words[i] == null)) {
                    number++;
                    if (e) { // 停用词
                        for (int j = 0; j < stopWords.length; j++) {
                            if (words[i].equals(stopWords[j])) {
                                number--;
                            }
                        }
                    }
                }
            }
            output.println(inputPath + ", 单词数: " + number);
        }

五、测试设计过程

1、"-c file.c":统计字符数

2、"-w file.c":统计单词总数

3、"-l file.c":统计行数

4、"-l -c -w file.c":同时满足上述条件,并打乱输入顺序

5、"-w -c -l file.c -o result2.txt":指定输出路径

6、"-w -c -s *.c":递归所有满足要求的文件

7、"-c -a -l 1.c -o result2.txt":统计行的类型并指定输出路径

8、"-w file.c -e stopList.txt":测试停用词表

9、"-c -l G:\\workspace\\test.c":测试指定的完整路径

10、"-w -l -s -c -a -e stopList.txt -o result2.txt G:\\workspace\\WordCount\\*.c":测试最复杂的路径

参考文献链接:

http://www.cnblogs.com/ningjing-zhiyuan/p/8563562.html  《第2周个人作业:WordCount》武剑洁

http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html  《现代软件工程讲义 2 工程师的能力评估和发展》邹欣

http://www.cnblogs.com/xinz/p/5044037.html  《现代软件工程讲义 源代码管理》邹欣

http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html  《Commit message 和 Change log 编写指南》阮一峰

http://blog.csdn.net/sunkun2013/article/details/13167099  《手把手教你如何把java代码,打包成jar文件以及转换为exe可执行文件》孙琨

Commit message 和 Change log 编写指南