个人项目 - wordCount(Java实现)

Posted zkyyo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了个人项目 - wordCount(Java实现)相关的知识,希望对你有一定的参考价值。

wordCount

1. 项目相关要求

项目Github地址

这个项目要求写一个命令行程序 ,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。 作为实战项目,我完成的要求如下:

  • 基本功能
    • -c 统计字符数(支持√)
    • -w 统计单词数(支持√)
    • -l 统计行数(支持√)
  • 扩展功能
    • -s 递归处理目录下符合条件的文件(支持√)
    • -a 返回更复杂的数据——代码行 / 空行 / 注释行(支持√)
    • 支持各种文件的通配符(支持√)
  • 高级功能
    • 基本的Windows GUI 程序操作(支持√)
    • 支持通过图形界面展现文件的信息(支持√)

 

2. 项目耗时预计(PSP)

实际耗时 PSP 表格在 blog 末尾给出

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

 

3. 解题思路

刚拿到题目时以为是一个简单的统计单词的程序,但是当认真阅读项目的要求后,发现基础功能实现比较简单,但是对于扩展功能有点不知道如何下手。主要原因是对于项目要求中给出的代码行、注释行的解释十分疑惑。

空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。

代码行:本行包括多于一个字符的代码。

注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:

? } //注释
在这种情况下,这一行属于注释行。

于是我决定先明确这些定义后再写代码,于是找了许多关于代码行和注释行的区别。最终发现最方便可以分辨这两者的工具是编辑器(或IDE),因为这些编辑器原生支持代码检查(当然记事本除外= =),可以区分出极端情况下究竟属于代码行还是注释行,譬如:

/** **/ int a = 3;

 

4. 设计实现过程

/view/MainView.java 负责显示 -x 参数打开的图形页面

/service/WordCount.java 负责处理命令行参数和代码计数

st=>start: 用户命令行输入
e=>end: 程序结束
cond=>condition: 是否含有 -x 参数

op_command=>operation: 命令行显示
op_view=>operation: 图形页面显示

st->cond
cond(yes)->op_view->e
cond(no)->op_command->e

 

5. 代码说明

以下是各参数实现的关键代码

  • 基本功能的实现
// /view/WrodCount.java
public void solution(File f) throws Exception {
    // 省略其他实现...
    while ((st = br.readLine()) != null) {
        text.append(st).append("
");

        // 基本功能
        // 匹配字符数
        totalCharacters += st.length();

        // 匹配函数
        totalLines++;

        // 匹配单词
        int words = 0;
        Pattern pattern = Pattern.compile("\\w+");
        Matcher matcher = pattern.matcher(st);
        while (matcher.find()) {
            words++;
        }
        totalWords += words;
    }
    // 省略其它实现...
}
  • 扩展功能的实现
public void solution(File f) throws Exception {
    // 省略...
    while ((st = br.readLine()) != null) {
        // 省略...
        // 扩展功能
        if (!f.getAbsolutePath().endsWith(".txt")) {
            int indexOfFirstQuote = st.indexOf(""");
            int indexOfSecondQuote = st.indexOf(""", indexOfFirstQuote + 1);
            if (indexOfFirstQuote != -1 && indexOfSecondQuote != -1) {
                st = st.substring(0, indexOfFirstQuote) + st.substring(indexOfSecondQuote + 1, st.length() - 1);
            } else if (indexOfFirstQuote != -1 && indexOfSecondQuote == -1) {
                st = st.substring(0, indexOfFirstQuote);
            }

            if (hasMultiLineComment) {
                commentLine++;
                int indexOfMultiLineCommentEnd = st.indexOf("*/");
                if (indexOfMultiLineCommentEnd >= 0) {
                    //  /*
                    //  abc
                    // >*/
                    hasMultiLineComment = false;
                }
            } else {
                if (st.trim().length() <= 1) { // 判断空行
                    blankLine++;
                } else {
                    int indexOfDoubleSlash = st.indexOf("//");
                    int indexOfMultiLineCommentBegin = st.indexOf("/*");
                    if (indexOfDoubleSlash == -1 && indexOfMultiLineCommentBegin == -1) { // 不存在注释
                        codeLine++;
                    } else if (indexOfDoubleSlash != -1 && indexOfMultiLineCommentBegin == -1) { // 只存在单行注释
                        commentLine++;
                    } else if (indexOfDoubleSlash == -1 && indexOfMultiLineCommentBegin != -1) { // 只存在多行注释
                        commentLine++;
                        hasMultiLineComment = true;
                        if (st.indexOf("*/") > indexOfMultiLineCommentBegin) { // 多行注释结束于同一行
                            hasMultiLineComment = false;
                        }
                    } else if (indexOfDoubleSlash != -1 && indexOfMultiLineCommentBegin != -1) { // 存在单行注释和多行注释
                        if (indexOfDoubleSlash < indexOfMultiLineCommentBegin) { // 单行注释在前
                            commentLine++;
                        } else { // 多行注释在前
                            commentLine++;
                            hasMultiLineComment = true;
                            if (st.indexOf("*/") > indexOfMultiLineCommentBegin) { // 多行注释结束于同一行
                                hasMultiLineComment = false;
                            }
                        }
                    }
                }
            }
        }
    }
}

 

6. 测试运行

文件测试

  • 测试空文本:

技术分享图片

  • 测试只有一个字符的文件:

技术分享图片

技术分享图片

  • 测试只有一个单词的文件:

技术分享图片

技术分享图片

  • 测试只有一行的文件:

技术分享图片

技术分享图片

  • 测试标准源文件:

技术分享图片

技术分享图片

参数测试

  • -s 递归测试

技术分享图片

  • 通配符?*支持

匹配所有扩展格式为 .txt 的文件

技术分享图片

匹配所有test_?.*的所有文件

技术分享图片

  • -x 显示图形化界面

技术分享图片

技术分享图片

覆盖性测试

技术分享图片

技术分享图片

 

7. 实际花费时间(PSP)

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

 

8. 项目小结

根据上面给出的 PSP 表可以很明显看出,我花在计划还有报告的时间基本和估计的时间差不多,但是开发的时间(约 940 minutes)却远远超出一开始的预计(550 minutes)。这里说明两点,一点是自己对实际开发持乐观的态度,因此导致对实际项目开发的时间估计较短;还有一点是开发的时间过长。

仔细看开发中具体哪一项花费的时间最多,我发现我花了几乎两倍的具体编码时间,现在回顾起来发现自己在浪费了大量时间在扩展功能的开发上,主要原因是在动手写代码前没有彻底明确需求(特别是对扩展部分注释行定义的理解),导致在写代码过程中删删改改,越写感觉越多bug,然后再推倒重来...因此教训就是前期要花更多的时间在需求分析上,从而避免在开发过程中频繁地改动已经写过的代码,降低整个开发效率。


以上是关于个人项目 - wordCount(Java实现)的主要内容,如果未能解决你的问题,请参考以下文章

个人项目wordCount

个人项目

WC 个人项目 ( node.js 实现 )

count.exe 个人项目

个人项目wordcount

个人项目wordcount