WordCount 实现与测试

WordCount 实现与测试

一、github地址

https://github.com/TCZdudu/WCProject

二、PSP表格

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

三、 解题思路

  • 看到这个题目后,首先想到的是要读文件和写文件操作。java有很多读取文件的方法,最终还是选择了BufferedReaderread()函数一次读取一个字符,而readline()一次读取一行。

  • 对字符,单词,行等等的判断,我马上想到了编译器里的词法分析,并不完全一样,但是大概得思路有一些。

  • 很复杂的是,对输入的不同命令要判断,并根据不同的命令执行不同的功能,并在输入的命令中找出不同文件名的作用。

  • 最后是java转成exe,至今没想通,要用exe测试为什么要用java写。

四、 程序设计实现过程

  • 代码主要函数有9个,主要就是每个不同命令的不同功能。

  • 实现统计字符、单词、行数着手,这就是对从文件读取的字符串的处理,很常规,也不是很麻烦。

  • 再进行对代码行分辨,递归处理文件和停用词功能。代码行的种类有两种///**///好判断,本行有就是代码行,/**/之间的代码也算代码行,所以有头就要有尾,记住头的位置,再找到末端位置就可以判断总的行数。空行也很简单,记录不在/**/内的空行或{ },用之前记录的总行数减掉这空行和注释行就得到代码行。停用词是统计停用词个数,减掉。

  • 实现了功能之后在处理输入命令后的分析,用条件语句去分析实现不同命令对应的不同功能实现。

五、 代码说明

介绍一下几个主要函数的实现

下面是获取停用词的函数,当输入-e时调用,先获取stoplist.txt中的词保存在一个list中,然后统计出现里面词的次数

public static List<String> get_stop(String args[])throws IOException{
        //包含“-e”时,获取stoplist中的单词作为停用词
        List<String> input_args = Arrays.asList(args);
        List<String> stop_words = new ArrayList<String>();
        if (input_args.contains("-e")) {
            int index = input_args.indexOf("-e");
            String stopFile = input_args.get(index + 1);
            BufferedReader buffer = null;
            buffer = new BufferedReader(new FileReader(stopFile));
            stop_words = getStopList(buffer);
        }
        return stop_words;
    }

  public static int get_stop_num(String filename,List<String> stop_list)throws IOException{
      //获取停用词数目
      FileReader f_obj = new FileReader(filename);
      BufferedReader b_obj = new BufferedReader(f_obj);
      String str;
      int num_stop=0;
      while ((str = b_obj.readLine()) != null) {
          for (String s : str.split(" ")) {
              for (String s1 : s.split(",")) {
                  if (s1.length() > 0 && stop_list.contains(s1)) {
                      num_stop++;
                  }
              }
          }
      }
      return num_stop;
  }

判断代码行、空行、注释行数目。先统计非注释的空行,再统计///**/类的代码行,最后总数目减去空行和注释行得到代码行

public static String get_line_info(String filename)throws IOException{
        //统计代码行、空行、注释行数目
        int blank_line_num =0,code_line_num = 0,note_line_num = 0;
        FileReader f_obj = new FileReader(filename);
        String result;
        BufferedReader b_obj = new BufferedReader(f_obj);
        int line_num = 0;
        String str_line = null;
        while ((str_line = b_obj.readLine()) != null) {
            if (str_line.length() == 0 || str_line.equals("{" )|| str_line.equals("}")) {
                blank_line_num++; //统计空行
            } else {
                for (int i = 0; i < str_line.length()-1; i++) {
                    boolean flag2=true;
                    while (str_line.charAt(i) != ' ' && str_line.charAt(i) != '\t' && flag2) {
                        if (str_line.charAt(i) == '/' && str_line.charAt(i + 1) == '/') {
                            note_line_num++; //统计//形式的注释行
                            i = str_line.length();
                            break;
                        } else if (str_line.charAt(i) == '/' && str_line.charAt(i + 1) == '*') {
                            boolean flag=true;//统计形如/**/的注释行数目
                            for (int t = str_line.length()-1; t >= 0; t--) {
                                while (str_line.charAt(t) != ' ' && str_line.charAt(t) != '\t'&& t>=1) {
                                    if (str_line.charAt(t) == '/' && str_line.charAt(t - 1) == '*') {
                                        t = -1;    //本行末尾结束 直接加1 并不进行后续代码
                                        flag =false;
                                        flag2=false;
                                        break;
                                    }
                                    else break;
                                }
                            }
                            note_line_num +=1;
                            while (flag) {  //非本行结束 往下判断 找到代码行结束位置
                                if((str_line = b_obj.readLine()) != null) {
                                    note_line_num++;
                                    line_num++;
                                    for (int j = str_line.length() - 1; j >= 0; j--) {
                                        while (str_line.charAt(j) != ' ' && str_line.charAt(j) != '\t' && j >= 1) {
                                            if(str_line.charAt(0) == '*' && str_line.charAt(j - 1) == '/' && str_line.length() > 2) {
                                                note_line_num -= 1;
                                                j = -1;
                                                flag = false;
                                                break;
                                            }
                                            else if (str_line.charAt(j) == '/' && str_line.charAt(j - 1) == '*') {
                                                j = -1;
                                                flag = false;
                                                break;
                                            }
                                            else break;
                                        }
                                    }
                                }
                            }
                        }
                        else {
                            break;
                        }
                    }
                }
            }
            line_num++;  //统计总代码行数
        }
        code_line_num = line_num - note_line_num -blank_line_num;  //代码行 = 总行数 - 空行 -注释行
        result = filename +",代码行/空行/注释行:"+ code_line_num +"/" + blank_line_num + "/" +note_line_num + "\r\n";
        return result;
    }

对输入的命令进行判断,实现不同的功能

public static void out_result(String filename,BufferedWriter file_writer,String args[],int args_len )throws IOException{
        String character_num= "",line_num="",line_info="", word_num = ""; //判定执行哪些命令
        int word_numb = -1;
        String arg;
        for (int i=0; i<args_len; i++){
            arg = args[i];
            switch (arg){
                case "-c":
                    character_num = get_character_count(filename);
                    break;
                case "-w":
                    word_numb = get_word_count(filename);
                    break;
                case "-l":
                    line_num = get_line_count(filename);
                    break;
                case "-a":
                    line_info = get_line_info(filename);
                    break;
                case "-e":
                    List<String> stop_list = get_stop(args);
                    int num_stop = get_stop_num(filename,stop_list);
                    word_numb -= num_stop;
            }
        }
        if(word_numb >=0){
            word_num = filename + ",单词数:"+ word_numb +"\r\n";
        }
        get_result(file_writer,character_num);
        get_result(file_writer,word_num);
        get_result(file_writer,line_num);
        get_result(file_writer,line_info);
    }

六、 测试设计过程

获取停用词数目代码测试:

 String str;
      int num_stop=0;
      while ((str = b_obj.readLine()) != null) {
          for (String s : str.split(" ")) {
              for (String s1 : s.split(",")) {
                  if (s1.length() > 0 && stop_list.contains(s1)) {
                      num_stop++;
                  }
              }
          }
      }
      return num_stop;

流程图如下

avatar

测试如下:

测试 输入 预期输出 实际输出
ABF EOF
ABCF 1 0 0
ABCDF 1 0 0
ABCDEF 1 1 1

获取结果代码测试:

 String character_num= "",line_num="",line_info="", word_num = ""; //判定执行哪些命令
        int word_numb = -1;
        String arg;
        for (int i=0; i<args_len; i++){
            arg = args[i];
            switch (arg){
                case "-c":
                    character_num = get_character_count(filename);
                    break;
                case "-w":
                    word_numb = get_word_count(filename);
                    break;
                case "-l":
                    line_num = get_line_count(filename);
                    break;
                case "-a":
                    line_info = get_line_info(filename);
                    break;
                case "-e":
                    List<String> stop_list = get_stop(args);
                    int num_stop = get_stop_num(filename,stop_list);
                    word_numb -= num_stop;
            }
        }
       

流程图如下

avatar

测试如下:

测试 输入 预期输出 实际输出
ABF 0
ABCG 1 1 1
ABDG 1 1 1
ABEG 1 1 1
ABFG 1 1 1

获取单词数的代码测试:

 int flag;
        int word_num = 0;
        boolean first_count = true;
        while((flag = b_obj.read()) != -1){
            if (first_count){
                if(flag != ',' && flag != ' ' && flag != '\n' && flag !='\r' && flag != '\t')
                    word_num += 1;
                first_count = false;
            }

            if (flag == ',' || flag == ' ' || flag == '\n'||flag =='\r' || flag == '\t' ){
                first_count = false;
                while((flag = b_obj.read()) != -1 ){
                    if (flag != ',' && flag != ' '&& flag != '\n' && flag !='\r' && flag != '\t'){
                        word_num ++;
                        break;
                    }
                }
            }
        }
        return word_num;

流程图如下

avatar

测试如下:

测试 输入 预期输出 实际输出
ABH 0
ABCDH 1 1 1
ABCFH 1 0 0
ABCFEGH 1 0 0
ABCDCFEGH 1 1 1

参考文献

posted @ 2018-03-20 20:09  TDonald  阅读(169)  评论(2编辑  收藏  举报