软件工程作业1-WordCount

github项目地址 https://github.com/bpgg/WordCount

预测PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 60  

· Estimate

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

30  

Development

开发

 600  

· Analysis

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

 100  

· Design Spec

· 生成设计文档

 60  

· Design Review

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

 60  

· Coding Standard

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

 30  

· Design

· 具体设计

 200  

· Coding

· 具体编码

 200  

· Code Review

· 代码复审

 100  

· Test

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

 30  

Reporting

报告

 100  

· Test Report

· 测试报告

 30  

· Size Measurement

· 计算工作量

 30  

· Postmortem & Process Improvement Plan

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

 100  

合计

     

项目要求及解题思路

实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。

基本功能

wc.exe -c file.c //返回文件 file.c 的字符数

  • 具体思路:使用io流读取目标文件的每一行,并累计每一行字符串的长度。

wc.exe -w file.c //返回文件 file.c 的词的数目

  • 具体思路:使用正则表达式确定所读取的每行字符串中所匹配到的单词数,进行累加。

wc.exe -l file.c //返回文件 file.c 的行数

  • 具体思路:直接累计读取的行数。

拓展功能

-s 递归处理目录下符合条件的文件。

  • 具体思路:
    1. 文件格式有要求,所以先写了一个文件名过滤器
    2. 判断传入参数是否为需求文件或者目录
    3. 递归查找,若为目标文件,输出文件名。若为目录,则递归查找。

-a 返回更复杂的数据(代码行 / 空行 / 注释行)。

  • 对需求的定义:
    1. 空行:整行为空白字符,或者空白字符加[{;}]

    2. 注释行:

      单行注释:[{;}]?//开头的视为注释行

      块注释:[{;}]?/开头,/(//s)+结尾的视为快注释中的行。 3. 代码行:文本总行数去掉空行和注释行。

高级功能:

-x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。

遇到的困难及解决方法

困难描述

在匹配注释行数中,对正则表达式不过熟悉,并且对于注释行可能出现的类型没有全面认识。

做过哪些尝试

放弃使用正则表达式,转而使用条件判断语句判断每一行数据。<br>
单行注释比较简单。<br>
多行注释要注意判断每行读取到是否含有/*,并且做标记,直到读到*/。<br>

是否解决

是的。不过最后还是使用正则表达式,因为代码比较简洁。

有何收获

熟悉了正则表达式的某些应用

设计实现过程

说明:使用两个类处理程序,一个Worker类用于实现特定需求,一个是Main类用于根据所输入参数调用相应方法实现需求。

代码说明

  • 单词数:

单词定义:只包含连续的英文字母,在这里没有考虑单词跨行的情况

 1     String REGEX ="\\b[a-zA-Z]+\\b";
 2         String currentLine;
 3         Pattern p = Pattern.compile(REGEX); 
 4         Matcher m;
 5         while((currentLine=reader.readLine())!=null) {
 6             currentLine=currentLine.trim();
 7              m= p.matcher(currentLine);
 8              while(m.find()) {
 9                  count++;
10              }
11         }
  • 字符数:

字符定义:包括空白字符

1     while((currentLine=reader.readLine())!=null) {
2             count+=currentLine.length();
3         }
  • 注释行数

注释行的定义上文已提及,在这里不再赘述。

 1 /*
 2     注释说明:
 3     单行注释:[{;}]?//开头的视为注释行
 4     块注释:[{;}]?/*开头,*/(//s)+结尾的视为快注释中的行。
 5     由此写出对应的正则表达式进行匹配。
 6 */
 7     String Single_Line_Note_REGEX="(\\s*)([{};]?)(\\s*)(//)(.*)";
 8     String Block_Note_Start_REGEX="(\\s*)([{};]?)(\\s*)(/{1})(\\*{1})(.*)";
 9     String Block_Note_End_REGEX="(.*)(\\*{1})(/{1})(\\s*)";
10         while((currentLine=reader.readLine())!=null) {
11             if(currentLine.matches(Single_Line_Note_REGEX)) {
12                 count++;
13             }else if(currentLine.matches(Block_Note_Start_REGEX)) {
14                 count++;
15                 while((currentLine=reader.readLine())!=null) {
16                     if(currentLine.matches(Block_Note_End_REGEX)) {
17                         count++;
18                         break;
19                     }else {
20                         count++;
21                     }
22                 }
23             }
24         }
  • 查询指定文件

根据输入参数指定文件和过滤类型

 1 /*
 2     思路分析:递归判断输入参数是否为目录,若是递归查询,若为目标文件,则输出文件名。
 3 
 4 */
 5   public class myFileFilter implements FileFilter {    
 6         @Override  
 7         public boolean accept(File file) {  
 8 
 9             if(file.isDirectory())  
10                 return true;  
11             else{  
12                 String name = file.getName();  
13                 if(name.endsWith(getFile_type())){
14                     return true;  
15                 }  
16                 else {
17                     return false;  
18                 } 
19             }  
20               
21         }  
22       
23     }  
24     public void getAllFilePath(String rootPath)  {  
25           
26         File file = new File(rootPath);  
27         File[] files = file.listFiles(new myFileFilter());  
28         for(int i=0;i<files.length;i++){  
29             if(files[i].isDirectory()){  
30                 getAllFilePath(files[i].getPath());  
31             }  
32             else{  
33                 System.out.println(files[i].getPath());  
34             }  
35         }               
36     }  

测试运行

基本功能的测试

高级功能测试

获取特殊行数

获取指定文件名

实际PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

  60  30

· Estimate

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

  30 30

Development

开发

600  600

· Analysis

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

 100  100

· Design Spec

· 生成设计文档

 60    60

· Design Review

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

 60  60

· Coding Standard

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

 30  

· Design

· 具体设计

 200  200

· Coding

· 具体编码

 200  180

· Code Review

· 代码复审

 100  60

· Test

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

 30  30

Reporting

报告0

 100  160

· Test Report

· 测试报告

 30  30

· Size Measurement

· 计算工作量

 30  30

· Postmortem & Process Improvement Plan

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

 100  80

合计

   760 790

项目小结

不足之处

  • 代码不够简洁,数据没有封装好:在观察了其他同学提交的作业,我深深感到自己编写的代码规范性不好,没有对所有代码的封装保持一致的风格。数据封装这方面没有把相关常量定义在一个接口文件中。

学习收获

  • 正则表达式:对正则表达式重新了解并做了笔记
  • javaAPI中的一些方法:文件名过滤器,分割字符串,去除字符串空白字符。

猜你喜欢

转载自www.cnblogs.com/fyy30/p/9644348.html