Word Count(Java)
本次作业readme
一、github地址:https://github.com/ShangYingying/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 // 停用词表,统计文件单词总数时,不统计该表中的单词
三、PSP表格:
PSP2.1 | PSP阶段 | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 15 |
Estimate | 估计这个任务需要多少时间 | 20 | 15 |
Development | 开发 | 1500 | 1340 |
Analysis | 需求分析(包括学习新技术) | 300 | 240 |
Design Spec | 生成设计文档 | 0 | 0 |
Design Review | 设计复审(和同事审核设计文档) | 0 | 0 |
Coding Standard | 代码规范 | 0 | 0 |
Design | 具体设计 | 0 | 0 |
Coding | 具体编码 | 1200 | 900 |
Code Review | 代码复审 | 0 | 0 |
Test | 测试 | 180 | 200 |
Reporting | 报告 | 180 | 270 |
Test Report | 测试报告 | 165 | 260 |
Size Measurement | 计算工作量 | 15 | 10 |
Postmortem&Process Improvement Plan | 事后总结,并提出过程改进计划 | 0 | 0 |
Total | 合计 | 1700 | 1630 |
四、解题思路:
1、将Java代码打包为jar文件,并转为exe可执行文件:拿到作业首先想到的是写了一个小程序,学会如何生成exe文件,以便检查电脑环境配置,附上exe4j下载地址;
2、读写文件:本次作业读写文件是很重要的一部分,通过网上查找代码方法,学会了几种读写文件的方法;
3、基本功能的实现:分别通过按字节、按行读取文件的方式实现;
4、控制台wc.exe [parameter] [input_file_name]指令形式的实现:字符串数组接受控制台指令串后将每个指令分解出来;
5、使用正则表达式识别各行中的符号或字符,以判断改该行是代码行、注释行或空行;
6、单词停用:split法分解出stoplist的每个单词,与待处理文件比较;
7、递归处理文件;
五、程序设计实现过程:
本次项目所有的函数我都放在一个类里
1、主方法:
接受到控制台传进来的命令字符串,将其分解成单个命令后进行判断,进入各分支;
2、各分方法:
①数字符方法:readfile_char(String file)
②数单词方法:readfile_word(String file)
③数行数方法:readfile_line(String file)
④写入文件方法:writefile(String file,String array)
⑤统计代码行注释行空行:wc2(String file)
⑥有停用词表时的数单词数:stop_word(String file1,String file2)
⑦处理文件夹内部文件:readfiles(String fileDir)
下面给出各个函数之间的调用关系流程图:
六:部分代码说明:
1、数字符和数行数我采用的都是按行读取文件的方式
基本结构:
FileReader fr = new FileReader(file); //fr指向文件
@SuppressWarnings("resource")
BufferedReader br = new BufferedReader(fr);
String line=br.readLine();
while (line!= null)
{
i_char+=line.length();
line=br.readLine();
}
2、数单词采用单个字符读文件的方式
基本结构:
FileReader fr_char = new FileReader(file);
int ch = 0;
int wordNum=1;
int flag=1;//遇到字母时置为1,遇到空格逗号等单词分隔符是置为0
while((ch=fr_char.read())!=-1)//等于-1表示读到了文件尾
{
if((ch==32||ch==10||ch==44||ch==46||ch==33)&flag==1)
//数字分别表示空格、换行、逗号、句号、感叹号
{
wordNum++;//此处保证了两个符号分割单词不会数错
flag=0;
}
else
flag=1;
}
3、将各功能结果连接起来便于输出到输出文件中
基本结构:
例如:
WRITE=new StringBuilder().append("\r\n").append(file).append(",").append(" 行数:").append(lineNum).toString();
4、使用正则方法查找注释行代码行和空行
基本结构:
//content表示读出文件的每一行,将其与注释行和空行特有的字符匹配,从而得出此行的类型
while (content!= null)
{
line++;
/空行
String null_type1="\\s*";
String null_type2=".\\s*";
if(content.matches(null_type1)||content.matches(null_type2))
{
nullNum++;
}
/注释行//
String explain_type1="//.*"; //两个斜杠加任意字符
String explain_type2="//\\s*"; //两个斜杠加上任意数量的空格
String explain_type3=".//"; //一个任意字符加上两个斜杠
String explain_type4=".//.*"; //一个任意字符加上两个斜杠和任意字符
String explain_type5="/*"; //用/*表示注释
if(content.matches(explain_type1)||content.matches(explain_type2)||content.matches(explain_type3)||content.matches(explain_type4)||content.matches(explain_type5))
{
explainNum++;
}
content=br.readLine();
}
5、停用表内单词的匹配
基本结构:
int stopNum=0;
FileReader fr = new FileReader(file1); //待处理文件
BufferedReader br = new BufferedReader(fr);
FileReader fr_s = new FileReader(file2); //停用表
@SuppressWarnings("resource")
BufferedReader br_s = new BufferedReader(fr_s);
String BR=br.readLine();
String BR_s=br_s.readLine();
String b=BR_s;
while(BR!=null)
{
int j=0;
String[] array=BR.split("\\s+|,"); //split分离每个单词
stopNum+=array.length;
while(j<array.length) //对于待处理文件每一行的每个单词
{
int k=0;
b=BR_s;
while (b != null)
{
String[] array_s=BR_s.split("\\s+|,");
while(k<array_s.length)
{
if(array[j].equals(array_s[k])) //都与停用表每一行的每一个单词比较,相同就减一
stopNum--;
System.out.print(array_s[k]);
k++;
}
b=br_s.readLine();
}
System.out.print(array[j]);
j++;
}
BR=br.readLine();
}
七:设计测试用例
主程序图:
根据程序图可以设计16个测试用例,以下列举十个覆盖了所有路径的用例:
编号 | 路径 | 对应命令 |
---|---|---|
1 | qrstxuvw | wc.exe |
2 | ACDFFGHJKMNPQRTUVXZabefhiklmo | wc.exe -c -w -l -a input.txt |
3 | ABFGHJKLPQRTxuvw | wc.exe -c -w input.txt -o output.txt |
4 | ABFGHJKLPQRTUVZabefgklmo | wc.exe -c -w -l -a input.txt -o output.txt |
5 | ACEGHJKMOQRTxuvw | wc.exe -c -w input.txt -e stoplist.txt |
6 | ACEGHJKMOQRTUMYabefhjlmo | wc.exe -c -w -l -a input.txt -e stoplist.txt |
7 | ABEGHJKLOQRTUVYabefgjlmo | wc.exe -c -w -l -a input.txt -e stoplist.txt -o output.txt |
8 | ABFGIKLPQSUVZadfgkln | wc.exe -s -c -w -l -a input -o output.txt |
9 | ACDEIKMNOSUWXYdfhijn | wc.exe -s -c -w -l -a input -e stoplist.txt |
10 | ABEHKLOSUVYdfgjn | wc.exe -s -c -w -l -a input -e stoplist.txt -o output.txt |
以工程文件夹下的.txt文件为例(也可换为.c文件):
待读文件:input.txt 输出到文件:output.txt 停用词表:stoplist.txt
文件夹input内含文件file1.txt和file2.txt
编号 | 参数 | 参数意义 | 输出 |
---|---|---|---|
1 | wc.exe | 未做任何处理 | 无输出 |
2 | wc.exe -c -w -l -a input.txt | 对文件input.txt进行数字符、数单词、数行数和统计代码行空行注释行处理 | input.txt, 字符数:32 input.txt, 单词数:8 input.txt, 行数:6 input.txt, 代码行/ 空行/ 注释行:2/2/2 |
3 | wc.exe -c -w input.txt -o output.txt | 统计input.txt的字符数单词数并将结果输进output.txt | 如下图 |
4 | wc.exe -c -w -l -a input.txt -o output.txt | 统计input.txt的字符数单词数行数和统计代码行空行注释行并将结果输进output.txt | 如下图 |
5 | wc.exe -c -w input.txt -e stoplist.txt | 统计input.txt的字符数和减去停用的单词数 | input.txt, 字符数:32 input.txt,单词数(有停用):6 |
6 | wc.exe -c -w -l -a input.txt -e stoplist.txt | 统计input.txt的字符数,行数,代码行空行注释行和减去停用的单词数 | input.txt, 字符数:32 input.txt,单词数(有停用):6 input.txt, 行数:6 input.txt, 代码行/ 空行/ 注释行:2/2/2 |
7 | wc.exe -c -w -l -a input.txt -e stoplist.txt -o output.txt | 统计input.txt的字符数,行数,代码行空行注释行和减去停用的单词数并输入文件output | 如下图 |
8 | wc.exe -s -c -w -l -a input -o output.txt | 统计input下所有文件的字符数,行数,代码行空行注释行和单词数并输入文件output | 如下图 |
9 | wc.exe -s -c -w -l -a input -e stoplist.txt | 统计input下所有文件的字符数,行数,代码行空行注释行和停用后单词数并输入文件output | input\file1.txt, 字符数:11 input\file2.txt, 字符数:12 input\file1.txt,单词数(有停用):5 input\file2.txt,单词数(有停用):4 input\file1.txt, 行数:4 input\file2.txt, 行数:4 input\file1.txt, 代码行/ 空行/ 注释行:0/2/2 input\file2.txt, 代码行/ 空行/ 注释行:2/1/1 |
10 | wc.exe -s -c -w -l -a input -e stoplist.txt -o output.txt | 所有功能 | 如下图 |
(可直接运行bin文件夹下面的测试脚本wc.bat)运行完全部十个用例之后的控制台和output.txt:
测试评价
主函数内包含16个判断节点,每个判断只有一个条件,十个测试用例覆盖了全部的路径,满足了判定覆盖、条件覆盖和路径覆盖
本文引用链接:
http://blog.csdn.net/sunkun2013/article/details/13167099
http://blog.csdn.net/hlf1203/article/details/50071201
https://www.cnblogs.com/bayes/p/5478862.html
http://blog.csdn.net/salonhuang/article/details/74560908
http://www.runoob.com/java/java-regular-expressions.html
http://blog.csdn.net/u014039577/article/details/50327979