第二周作业 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;
}
 

原文地址:https://www.cnblogs.com/Donoth/p/8597025.html

时间: 2024-11-08 13:04:24

第二周作业 WordCount的相关文章

软件测试第二周作业 wordcount

软件测试第二周作业 wordcount Github地址 https://github.com/mxz96102/word_count PSP2.1表格 PSP2.1 PSP 阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划 25 30 · Estimate · 估计这个任务需要多少时间 150 252 Development 开发     · Analysis · 需求分析 (包括学习新技术) 20 20 · Design Spec · 生成设计文档 0 0 · Desig

软件质量与测试第二周作业 WordCount

第二周作业 WordCount 一.Github 地址 https://github.com/llag9810/Software-Quality-and-Testing-Wordcount 二.PSP2.1 表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划 60 25 · Estimate · 估计这个任务需要多少时间 30 15 Development 开发 600 810 · Analysis · 需求分析 (包括学习新技术) 60 60 · D

第二周作业wordcount

github项目链接https://github.com/liqia/WordCount 1.项目简介 对程序设计语言源文件统计字符数.单词数.行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件. 可执行程序命名为:wc.exe,该程序处理用户需求的模式为: wc.exe [parameter] [input_file_name] 存储统计结果的文件默认为result.txt,放在与wc.exe相同的目录下. 2.项目psp表格 PSP2.1表格 PSP2.1

解题报告——2018级2016第二学期第二周作业

解题报告——2018级2016第二学期第二周作业 D:迷宫问题 题目描述: 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线. 输入 一个5 × 5的二维数组,表示一个迷宫.数据保证有唯一解. 输出 左上角到右

马哥linux 培训第二周作业

注意:第二周作业,请将以下题目整理在51cto博客当中,完成后请将对应的博文链接地址提交在答案栏中,提交格式如下:学号+姓名+博文链接地址eg:1+张三+http://mageedu.blog.51cto.com/4265610/1794420 本周作业内容:1.Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示. 文件管理的命令有cp.mv.rm 复制命令:cp 用法: cp [-adfilprsu] 来源文件(source) 目标文件(destination) cp [o

第二周作业补交(请老师看一下)

#include<stdio.h> #include<math.h> int main(void) { int money,year; double rate,sum; printf("Enter money:"); scanf("%d",&money); printf("Enter year:"); scanf("%d",&year); printf("Enter rate:

魏昊卿——《Linux内核分析》第二周作业:了解操作系统是怎样工作的

魏昊卿——<Linux内核分析>第二周作业:了解操作系统是怎样工作的 一.实验部分 使用实验楼的虚拟机打开shell cd LinuxKernel/linux-3.9.4 qemu -kernel arch/x86/boot/bzImage 然后cd mykernel 您可以看到qemu窗口输出的内容的代码mymain.c和myinterrupt.c 使用自己的Linux系统环境搭建过程参见mykernel,其中也可以找到一个简单的时间片轮转多道程序内核代码 mymain.c myinterr

学习linux第二周作业

第二周作业: 本周作业内容: 1.Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示. touch,rm,mv,cp,file,ls,chmod,chown,ln,rename, touch 修改文件atime,如果文件不存在,那么创建该文件. rm:删除文件. -r:循环删除,包含文件和目录 -f:强制删除,布询问. -i:询问是否删除. 默认情况下,系统自带别名,rm=rm -i mv:移动文件,可以在移动的过程中重命名文件或文件夹. 例如:移动重命名mytest1目录为

软件工程 第二周作业

##软件工程第二周作业 提出问题 1. 一般来说,想要自己的程序跑得又快又好,就要减少函数的反复调用,但有所得则必有所失,效能提高就有可能伴随着程序的稳定性的降低,这两者应该如何权衡呢? 2. 关于5.3.5 老板驱动的流程,这种开发流程模式存在着一些问题,那要如何解决这些问题呢? 这种模式当然也有它的问题. 领导对许多技术细节是外行. 领导未必懂得软件项目的管理,领导的权威影响了自由的交流和创造. 领导最擅长的管理方式是行政命令,这未必能管好软件团队或任何需要创造力的团队. 领导的精力有限,领