zoukankan      html  css  js  c++  java
  • 第2周个人作业:WordCount

    • Github项目链接:

      https://github.com/JarrySmith/WC


    • PSP表格:

    PSP2.1

    PSP阶段

    预估耗时

    (分钟)

    实际耗时

    (分钟)

    Planning

    计划

     10

     5

    · Estimate

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

     10

     5

    Development

    开发

     825

     1100

    · Analysis

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

     200

     300

    · Design Spec

    · 生成设计文档

     30

     60

    · Design Review

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

     20

     30

    · Coding Standard

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

     15

     20

    · Design

    · 具体设计

     30

     30

    · Coding

    · 具体编码

     400

     450

    · Code Review

    · 代码复审

     30

     60

    · Test

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

     100

     150

    Reporting

    报告

     60

     70

    · Test Report

    · 测试报告

     30

     40

    · Size Measurement

    · 计算工作量

     10

     10

    · Postmortem & Process Improvement Plan

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

     20

     20

     

    合计

     890

     1175


    • 解题思路

              首先很明显,分为包含-s的目录寻找以及非目录寻找的其他命令,我采取的是遍历命令行参数,获取需要进行的操作,如计算单词,计算行数等等.然后有些选项如-o,-e则在第一遍遍历的时候进行检测,其后面是不是有指定文本,如果指定了,那么把输出指向该文本,如果没有指定,那么就直接报错,不需要执行接下来的命令,加快了速度.

         说到文本,那就有关于文本读写方面的内容,我参考了博客【1】中的文本操作。递归遍历参考了博客【2】,获取当前路径参考了博客【3】

       再统计字符,单词,行数比较简单,不多说.值得注意的是-s和-a。-s需要指定特定目录下的指定类型的文本,这里牵涉到关于文本类型的过滤,是默认当前目录还是命令行传入的目录.*.type可以单独存在也可接在目录后面,这都是需要在遍历的时候去解析的。至于-a,自然是关于注释行,空行,代码行的判断了,我的实现是,先判断是不是空行,再判断是不是注释行,如果都不是,那就是代码行.其中有一种是多行注释的最后加上了代码,算是代码行,关于这个,在多行结束判断中,加入一个判断最后一个字符是否为'/'。

             对于每个选项的细节实现上不做过多的展开.稍后的代码展现可以再看到具体的.


    •   程序设计实现过程

        由于工程量不大,所以把所有函数写在一个类里静态调用.共十一个函数.

      countchars、countlines、count_word分别统计字符数,行数,单词数
      is_emptyline、is_expline 用来判断是否为空行,注释行,是被countdetail调用
      get_stopword、readToString、saveresult都是辅助函数,功能为获取停用词表的词,将读入的文本转化为字符串,保存统计结果

    WC、traversepath为两个关键的入口函数,根据是否包含-s分为两个部分去进行统计工作

    
    
    • 代码说明

       1.WC函数,关键入口函数,解析命令行参数表.在第一遍遍历进行了错误判断,利用param是否包含-s进行分支选择,分别处理

    public static void WC(String[] args) {
            int words = 0;
            int lines = 0;
            int chars = 0;
            int[] detail = new int[3];
    
            CharSequence save = ".txt";
            String filepath = null;
    
            boolean checked_file = false;
            for (int i = 0; i < args.length; i++) {
                if (args[i].contains(".txt")) continue;
                //停用词的文件判断
                if (args[i].equals("-e")) {
                    if (i == args.length - 1) {
                        System.out.println("没有指定停用词文本");
                        err = true;
                    } else if (!(args[i + 1].contains(save))) System.out.println("停用词文本需紧跟在-e后");
                    else stop_path = args[i + 1];
                }
                //判断是否函数输出文本
                if (args[i].equals("-o")) {
                    if (i == args.length - 1) {
                        System.out.println("没有指定输出结果文本");
                        err = true;
                    } else if (!(args[i + 1].contains(save))) System.out.println("result.txt需紧跟在-o后");
                    else save_path = args[i + 1];
                }
                string_args.append(args[i]);
            }
            param = string_args.toString();
            if (!err) {
                if (param.contains("-s")) {
                    //默认path为当前目录
                    String path =  System.getProperty("user.dir");
                    for (int i = args.length - 1; i > 0; i--) {
                        if (args[i].contains("*.")) {
                            //获取指定文件类型和指定目录
                            if(args[i].length()>15) path= args[i].split("\.")[0].replace("*","");
                            filetype = "." + args[i].split("\.")[1];
                        }
                    }
                    //开始遍历目录
                    traversepath(path);
                } else {
                    //错误判断
                    for (int i = 0; i < args.length; i++) {
                        if (args[i].contains("*.")){err=true;System.out.println("只有输入-s才能进行全目录遍历规定文件");}
                        if (args[i].contains(".")) {
                            filepath = args[i];
                            break;
                        }
                    }
                if(!err)
                {
                    //及非遍历统计
                if (param.contains("-c")) chars = countchars(filepath);
                if (param.contains("-l")) lines = countlines(filepath);
                if (param.contains("-w")) words = count_word(filepath);
                try {
                    if (param.contains("-a")) detail = countdetail(filepath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                }
            }
        }
            saveresult(words,lines,chars,detail,filepath);
            }

        2.traversepath函数 根据特定的文本类型,遍历指定目录及其子目录,分别进行统计工作然后保存

    public static void traversepath(String path) {
            File file = new File(path);
            if (file.exists()) {
                File[] files = file.listFiles();
                //如果是个空文件夹
                if (files.length == 0) {
                    return;
                } else {
                    for (File file2 : files) {
                        if (file2.isDirectory()) {
                            //遍历子目录
                            traversepath(file2.getAbsolutePath());
                        } else {
                            String filename = file2.getName();
                            if (filename.endsWith(filetype)) {
                                String filepath = path + '\' + filename;
                                int words = 0;
                                int lines = 0;
                                int chars = 0;
                                int[] detail = new int[3];
                                //根据参数进行统计
                                try {
                                    if (null == param) break;
                                    if (param.contains("-a")) detail = countdetail(filepath);
                                    if (param.contains("-w")) words = count_word(filepath);
                                    if (param.contains("-c")) chars = countchars(filepath);
                                    if (param.contains("-l")) lines = countlines(filepath);
                                    saveresult(words, lines, chars, detail, filename);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            }
        }

    • 测试设计过程

    如何设计?覆盖所有判断路径,分支

      关于命令行参数不完整和不正确 会导致程序高风险

      测试用例设计如下:

    1. wc.exe -l a.c
    2. wc.exe -w a.c
    3. wc.exe -c a.c
    4. wc.exe -a a.c
    5. wc.exe -l a.c -o result.txt
    6. wc.exe -l a.c -o
    7. wc.exe -w a.c -e stoplist.txt
    8. wc.exe -w a.c -e
    9. wc.exe -s -a *.c
    10. wc.exe -s -a
    11. wc.exe -s -a *.java

      测试脚本代码如下:

    wc.exe -l a.c
    wc.exe -w a.c
    wc.exe -c a.c
    wc.exe -a a.c
    wc.exe -l a.c -o result.txt
    wc.exe -l a.c -o
    wc.exe -w a.c -e stoplist.txt
    wc.exe -w a.c -e
    wc.exe -s -a *.c
    wc.exe -s -a
    wc.exe -s -a *.java
    pause>nul


    • 参考文献链接

      【1】https://www.cnblogs.com/oracleblogs/p/6591656.html

      【2】https://www.cnblogs.com/azhqiang/p/4596793.html

      【3】https://www.cnblogs.com/franson-2016/p/5728280.html

     

  • 相关阅读:
    高级(线性)素数筛
    Dijkstra(迪杰斯特拉)算法
    简单素数筛
    【解题报告】 POJ1958 奇怪的汉诺塔(Strange Tower of Hanoi)
    4 jQuery Chatting Plugins | jQuery UI Chatbox Plugin Examples Like Facebook, Gmail
    Web User Control Collection data is not storing
    How to turn on IE9 Compatibility View programmatically in Javascript
    从Javascrip 脚本中执行.exe 文件
    HtmlEditorExtender Ajax
    GRIDVIEW模板中查找控件的方式JAVASCRIPT
  • 原文地址:https://www.cnblogs.com/Jarry-smith/p/8597560.html
Copyright © 2011-2022 走看看