Github地址
https://github.com/liuqianx/liuqianx
PSP表格
PSP2.1 | PSP阶段 | 预估耗时 (分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 10 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 575 | 700 |
· Analysis | · 需求分析 (包括学习新技术) | 60 | 60 |
· Design Spec | · 生成设计文档 | 30 | 30 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 5 | 10 |
· Design | · 具体设计 | 30 | 60 |
· Coding | · 具体编码 | 300 | 550 |
· Code Review | · 代码复审 | 30 | 100 |
· Test | · 测试(自我测试,修改代码,提交修改) | 100 | 320 |
Reporting | 报告 | 45 | 55 |
· Test Report | · 测试报告 | 30 | 40 |
· Size Measurement | · 计算工作量 | 5 | 5 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 10 | 10 |
合计 | 900 | 1450 |
解题思路
- 首先题目要求对输入的不同参数输出不同的结果,所以需要用到main函数的args参数,所以首先就要完成对参数的识别。
- 然后就是要进行文件的读取和写入,需要去了解一下java关于文件的类。
- 后面关键就是主要功能的实现,这些功能很像我们上学期编译原理上做的词法分析,因为决定使用正则表达式来匹配各种需要统计的数据的模式,然后对读取的字符串进行分割,然后数出其中元素的个数。
- 最后就是了解java如何打包成jar包,然后使用exe4j转成exe的格式。
程序设计实现过程
我是采用java语言来实现程序。设计了一个类WC,其中前三个功能比较简单,因此没有单独创建一个函数,主要是使用正则表达式来对各种需要统计的数据进行模式识别,类中的主要几个方法如下:
WC()
public void readFile(String filepath)
public void readStopList(String filepath)
public int getCommLine()
public int getBlankLine()
public int getStopNum()
public void writeFile(String fileName, String content)
代码说明
- 首先是用一个函数来读取文件并存入一个String变量中
public void readFile(String filepath)
{
try
{
InputStream f = new FileInputStream(filepath);
int size = f.available();
for(int i=0; i<size; i++)
{
buffer += (char)f.read();
}
}
catch(IOException e)
{
System.out.println("error");
}
}
- 对前三个功能,即对单词数,字符数,总行数的统计比较简单,只需用String类的spilt(regex)方法,用对应的正则表达式就可以直接将输入字符进行分割,然后数出元素的个数即可:
//字符数
int charNum = wc.buffer.length();
//单词数
int wordNum = wc.buffer.split("\\s+|,").length;
//总行数
int lineNum = wc.buffer.split("\\n").length;
- 对于空行的统计只需用Matcher类来寻找到所有符合Pattern为
"(?<=\\n)\\s*?\\n"
的正则表达式即可:
public int getBlankLine()
{
//空行
Pattern blank = Pattern.compile("(?<=\\n)\\s*?\\n");
Matcher m3 = blank.matcher(buffer);
int blankLine = 0;
while(m3.find())
{
blankLine++;
}
return blankLine;
}
- 对于注释行,有两种情况,第一种是单行注释,用
"(\\/\\/[^\\n]*)"
来匹配,另外一种情况是多行注释,用"(\\/\\*([^\\*^\\/]*|[\\*^\\/*]*|[^\\**\\/]*)*\\*\\/)"
来进行匹配,代码如下:
public int getCommLine()
{
Pattern comment1 = Pattern.compile("(\\/\\/[^\\n]*)");
Pattern comment2 = Pattern.compile("(\\/\\*([^\\*^\\/]*|[\\*^\\/*]*| [^\\**\\/]*)*\\*\\/)");
Matcher m1 = comment1.matcher(buffer);
Matcher m2 = comment2.matcher(buffer);
int commLine, commLine1, commLine2 ;
commLine = commLine1 = commLine2 = 0;
while(m1.find())
{
commLine1++;
}
while(m2.find())
{
commLine2 = m2.group().split("\\n").length;
}
commLine = commLine1 + commLine2;
return commLine;
}
- 空行数则是总行数-注释行-空行。
- 最后是对文件的写出:
public void writeFile(String fileName, String content)
{
File root = new File("");
OutputStream fos;
try
{
fos = new FileOutputStream(root.getAbsolutePath() + "\\" + fileName);
System.out.println(root.getAbsolutePath() + "\\" + fileName);
OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");
writer.append(content);
writer.close();
fos.close();
}catch (Exception e)
{
System.out.println(e);
}
}
测试设计过程
白盒测试:
根据软件产品的内部工作过程,在计算机上进行测试,以证实每种内部操作是否符合设计规格要求,所有内部成分是否已经过检查。这种测试方法就是白盒测试。白盒测试把测试对象看做一个打开的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。
采用白盒测试中的语句覆盖和判断覆盖原则,针对WC类中的所有的get方法,对于每一组参数设计测试用例,使用语句覆盖指标设计测试用例。
测试文件file.c:
asd asdas dq
wd as
//asd
sadds asd
/* asd asd
sad
asd */
输入 | 预期输出 | 实际输出 |
---|---|---|
wordCount.exe -w file.c | 单词数:14 | 单词数:14 |
wordCount.exe -l file.c | 总行数:10 | 总行数:10 |
wordCount.exe -c file.c | 字符数:59 | 字符数:59 |
wordCount.exe -w -l -c file.c | 字符数:59 单词数:14 总行数:10 | 字符数:59 单词数:14 总行数:10 |
wordCount.exe -a file.c | 代码行/空行/注释行:3/3/4 | 代码行/空行/注释行:3/3/4 |
wordCount.exe -w -l -c -a file.c | 字符数:59 单词数:14 总行数:10 代码行/空行/注释行:3/3/4 | 字符数:59 单词数:14 总行数:10 代码行/空行/注释行 :3/3/4 |
wordCount.exe -w -l -c -o output.txt | output.txt | output.txt |
wordCount.exe -w -a file.c -e stopList.txt | 单词数:9 代码行/空行/注释行:3/3/4 | 单词数:9 代码行/空行/注释行 :3/3/4 |
wordCount.exe -a -w | IOError | IOError |
总结:正确输入都能够输出正确的结果,错误的输入能输出对应的错误提示。