第二周作业 WordCount

Posted donoth

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二周作业 WordCount相关的知识,希望对你有一定的参考价值。

https://github.com/HuangDongPeng/WordCount.git


1.1  PSP

PSP2.1

PSP阶段

预估耗时

(分钟)

实际耗时

(分钟)

Planning

计划

 30

 30

· Estimate

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

 5h

 12h

Development

开发

 2h

 4h

· Analysis

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

30min

 30min

· Design Spec

· 生成设计文档

 -

 -

· Design Review

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

 -

· Coding Standard

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

 5min  

5min

· Design

· 具体设计

 10

0

· Coding

· 具体编码

2h

 3h

· Code Review

· 代码复审

 10

 10

· Test

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

 2h

 3h

Reporting

报告

 1h

 1h

· Test Report

· 测试报告

 

 

· Size Measurement

· 计算工作量

 

 

· Postmortem & Process Improvement Plan

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

 20min

 30min

 

合计

8h

12h







































2.1  WordCount需求说明

WordCount的需求可以概括为:对程序设计语言源文件统计字符数、单词数、行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。

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

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

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

wc.exe -o outputFile.txt     //将结果输出到指定文件outputFile.txt

wc.exe -s            //递归处理目录下符合条件的文件

wc.exe -a file.c     //返回更复杂的数据(代码行 / 空行 / 注释行)

wc.exe -e stopList.txt  // 停用词表,统计文件单词总数时,不统计该表中的单
2.2 解题思路及分析过程
功能实现
1.单词统计
按字符流读取文件,对每一个字符做判断,如果不是换行符或空格则继续往下读取;当读取到换行符或者空格是,将前面读到的字符拼作一个单词
,单词计数加一:

while ((tempChar = reader.read()) != -1) {
            if ((tempChar >= 65 && tempChar <= 90) || (tempChar >= 97 && tempChar <= 122)) {
                isChar = true;
            } else {
                if (isChar) {
                    isChar = false;
                    wordCount++;
                }
                continue;
            }
        }



  

 



2.字符计数
每读入一个字符,判断是不是回车换行符,不是则字符计数器加一:

while ((tempChar = reader.read()) != -1) {
            //判断是不是回车
            if (!(tempChar == 13 || tempChar == 10||tempChar==9))
                charCount++;
            character = (char) tempChar;
        }
        reader.close();

}

 

  

3.行数读取
调用java API,统计计数

        reader = new BufferedReader(new FileReader(file));
        String tempString = null;
        int line = 0;
        while ((tempString = reader.readLine()) != null) {
            line++;
        }
        reader.close();return line;

 


4.递归获取文件
获取文件目录,判断是不是目录,如果是目录则递归获取该目录下的内容;如果符合要求的文件,则先将文件名存储,与之后的执行一同进行

    File tmpFile = new File(dir);
    if (tmpFile.isDirectory()) {
        try {
            String[] fileNames = tmpFile.list();
            if (fileNames.length != 0) {
                for (String s : fileNames) {
                    String newPath = dir + "/" + s;
                    FindFile(newPath);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else {
        if (dir.contains(fomatName)) {
            int filePointIndex=dir.lastIndexOf(".");
            String rightFormatName=dir.substring(filePointIndex);
            if(rightFormatName.equals(fomatName))
                canBeFoundFile.add(dir);//存储符合后缀文件
        }
    }

 

5.获取不同类型的行数
获取代码行:非注释、非空的都是代码行
获取注释行:包含//或者包囊在 /* ..*/中的都是注释行,按字符读取,如果读取到/*则进入注释统计模式,直到读取到*/才退出该模式继续统计
获取空行:不解释

boolean isNote=false;
        reader = new BufferedReader(new FileReader(file));
        String tempString = null;
        int emptyLine = 0;
        int codeLine = 0;
        int noteLine = 0;
        while ((tempString = reader.readLine()) != null) {
            if(tempString.contains("/*")){
                isNote=true;
            }
            else if(tempString.contains("*/"))
            {
                isNote=false;
            }
            if (tempString.contains("//")||tempString.contains("*/")||isNote)
                noteLine++;
            else if (tempString.isEmpty() || IsEmpty(tempString)) {
                emptyLine++;
            } else
                codeLine++;
     

 

6.停用表功能
若存在于停用表中的单词则统计单词数时不计入统计。
先获取停用表中的单词,存储与List,然后读取指定文件单词做判断,若属于停用表中的则单词计数器不增加。

//读取停用表内容      
while ((tempChar = reader.read()) != -1) { if ((tempChar >= 65 && tempChar <= 90) || (tempChar >= 97 && tempChar <= 122)) { isChar = true; sb.append((char) tempChar); } else { if (isChar) { wordTable.add(sb.toString()); sb = new StringBuilder(); isChar = false; } continue; } } if (isChar && sb.length() != 0) { wordTable.add(sb.toString()); }//读取文件内容while ((tempChar = reader.read()) != -1) { if ((tempChar >= 65 && tempChar <= 90) || (tempChar >= 97 && tempChar <= 122)) { isChar = true; localSb.append((char) tempChar); } else { if (isChar) { if (!IsInTable(wordTable, localSb.toString())) { wordCount++; } localSb = new StringBuilder(); isChar = false; } continue; }

 

7.输出文件
修改输出文件名称,不解释


参数分析
在知道执行哪些命令前需要遍历一遍输入参数,存储要执行的指令,在统一结合递归获取文件等操作执行指令

//首先遍历一边参数,找出需要执行的指令   
for (int i = 0; i < inputArgs.length; i++) {
//如果使用了停用表指令,就获取停用表名
if (inputArgs[i].contains("-e")) { isUseStopList = true; i++; stopListFileName = inputArgs[i]; } //是否需要重新定义输出文件名并获取输出文件名 if (inputArgs[i].contains("-o")) { isOutPutFile = true; i++; outputFileName = inputArgs[i]; }
//是否递归搜索
if (inputArgs[i].contains("-s")) { isGetDirFiles = true; } }
//寻找目标文件,目标文件之前的都是执行参数
for (int i = 0; i < inputArgs.length; i++) { if (inputArgs[i].contains(".")) { fileNameIndex = i; filePath = inputArgs[i]; if (filePath.contains(".")) { int pointIndex = filePath.lastIndexOf("."); fomatName = filePath.substring(pointIndex); } break; } } if (!isGetDirFiles) { for (int i = 0; i < fileNameIndex; i++) { OrderJudge(inputArgs[i]); } } else { SetFileDir(inputArgs); FindFile(fileDir); for (String s : canBeFoundFile) { filePath = s; System.out.println(s); for (int i = 0; i < fileNameIndex; i++) { OrderJudge(inputArgs[i]); } } } //输出文件 OutPutFile(outputFileName, sb); }

 



2.3测试
编写测试,覆盖每一个函数及功能,每一个的形参包括:读取的文件名,预期的输入;
每一个调用的输出结果是:
测试名称、预期结果、测试输出结果、是否符合预期结果;

public boolean Test_CharCount(int expResult, String path) {
    return PrintErrorDetail(GetMethodName(), expResult, Main.ReadChar(path));
}
public boolean Test_WordCount(int expResult, String path) {
    return PrintErrorDetail(GetMethodName(), expResult, Main.ReadWord(path));
}
public boolean Test_LineCount(int expResult, String path) {
    return PrintErrorDetail(GetMethodName(), expResult, Main.ReadLine(path));
}
public boolean Test_ReadDiffLine(int emptyLine, int noteLine, int codeLine, String path) {
    int[] expResult = new int[3];
    expResult[0] = codeLine;
    expResult[1] = emptyLine;
    expResult[2] = noteLine;
    String[] lineNames = {"codeLine", "emptyLine", "noteLine"};
    int[] testResult = Main.GetDifferentLine(path);
    for (int i = 0; i < 3; i++) {
        PrintErrorDetail(GetMethodName() + " " + lineNames[i], expResult[i], testResult[i]);
        if (expResult[i] != testResult[i])
            return false;
    }
    return true;
}
public boolean Test_StopList(int expResult, String stoplistPath, String readFilePath) {
    int testResult = Main.StopWordTable(stoplistPath, readFilePath);
    return PrintErrorDetail(GetMethodName(), expResult, testResult);
}
public boolean Test_Recursion(int expFileCount, String path, String formateName) {
    Main.fomatName = formateName;
    return PrintErrorDetail(GetMethodName(), expFileCount, Main.FindFile(path));
}
public boolean Test_OutputFile(StringBuilder sb, String outputPath) {
    System.out.println("test: " + GetMethodName());
    if (Main.OutPutFile(outputPath, sb)) {
        System.out.println("out put file success");
        return true;
    }
    System.out.println("out put file failed");
    return false;
}
public boolean Test_Recursion_StopList(String formatName, String stopListName, int[] expCount) {
    Main.fomatName = formatName;
    Main.FindFile("./");
    boolean result = true;
    for (int i = 0; i < Main.canBeFoundFile.size(); i++) {
        if (!Test_StopList(expCount[i], stopListName, Main.canBeFoundFile.get(i))) {
            result = false;
        }
    }
    return result;
}
public boolean Test_Recusion_WordRead_OutputFile(String formatName, String outputFileName, int[] expResult) {
    Main.fomatName = formatName;
    Main.FindFile(Main.fileDir);
    boolean result = true;
    for (int i = 0; i < Main.canBeFoundFile.size(); i++) {
        if (expResult[i] != Main.ReadWord(Main.canBeFoundFile.get(i))) {
            result = false;
        }
    }
    if (result) {
        result = Main.OutPutFile(outputFileName, Main.sb);
    }
    return result;
}
 

 

以上是关于第二周作业 WordCount的主要内容,如果未能解决你的问题,请参考以下文章

第二周个人作业WordCount

软件测试第二周作业 wordcount

第二周作业wordcount

软件质量测试 第二周 wordcount 作业

软件测试第二周个人作业--wordcount

软件测试第二周个人作业WordCount程序实现