第一次个人编程作业
GitHub链接: https://github.com/wei-177/SE_Project1
这个作业属于哪个课程 | 计科12班 |
---|---|
这个作业要求在哪里 | 作业 - 论文查重 |
这个作业的目标 | 完成个人项目,实现论文查重软件的设计 |
一、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planing | 计划 | 30 | 50 |
Estimate | 估计这个任务需要多久时间 | 10 | 10 |
Development | 开发 | 300 | 480 |
Analysis | 需求分析(包括学习新技术) | 100 | 240 |
Design Review | 设计复审 | 20 | 20 |
Coding Standard | 代码规范 | 10 | 10 |
Design | 具体设计 | 30 | 30 |
Coding | 具体编码 | 240 | 180 |
Code Review | 代码复审 | 60 | 30 |
Test | 测试 | 60 | 120 |
Reporting | 报告 | 60 | 90 |
Test Report | 测试报告 | 20 | 20 |
Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 30 | 30 |
合计 | 980 | 1320 |
一、项目开发环境
1.编程语言: C++ 14
2.编程环境: Visual Studio Community
3.第三方库: cppjieba
4.性能分析工具: VS 性能分析工具
5.覆盖率计算工具: OpenCppCoverage
二、项目模块设计与实现
1.main函数:进行相关类和函数的调用。
2.Read函数:根据文件地址读取文本内容,并检测是否读取成功。
3.jieba类:第三方库包含的类,对文本进行关键词提取,过滤掉常见词。
4.getCosineSimilarity函数:根据提取的关键词数组,统计不同词的出现频率,并将两组词的频率看作两个n维空间向量,计算两个向量的余弦相似度。
5.项目整体流程图:
三、项目性能分析
1.时间性能分析:
由图可以看出时间大部用于数据的读入和第三方库的关键词提取上,优化空间较小。
2.空间性能分析:
图中程序运行过程中的6个快照的时刻分别为:
(1)程序进入main函数之后。
(2)程序调用Read函数读取文章内容之后。
(3)程序根据dict文件夹内文件初始化jieba类之后。
(4)程序根据jieba类对文章进行关键词提取并计算余弦相似度之后。
(5)程序执行cout命令,给出运行结果之后。
(6)程序结束,释放内存之后。
根据6个快照可以看出内存瓶颈在于jieba类的初始化操作,内存花销最高接近138MB。
对比第1和第6个快照,可以发现程序运行后内存增加了4KB左右,推测是cout操作开辟的缓冲区,判断程序没有发生内存泄漏。
四、项目单元测试
图中单元测试有14组测试样例,分别有6组正确输入的样例和8组错误输入的样例,结果均符合预期,main.cpp的覆盖率达到了100%。 以下为6组正确测试样例的命令行输入和其得到的余弦相似度:五、项目异常处理
1.输入异常处理:如果进行比较的文件路径错误,Read函数读取文件内容失败,返回false。
bool Read(string path, string &article) {//根据路径读取文件内容
ifstream file(path);
if (!file.is_open()) { //文件路径错误
return false;
}
article = "";
string temp;
while (file >> temp) {
article += temp;
}
file.close();
return true;
}
2.输出异常处理:如果输出路径错误导致无法找到/创建输出文件,程序报错结束。
ofstream file(argv[3]);
if (!file.is_open()) {
cout << "OutputPath Error!" << endl;
file.close();
return 0;
}
3.文件空白异常处理:如果比较的文件存在空白文件,则通过jieba类提取得到关键词数组为空,检测到后程序报错结束。
jieba.extractor.Extract(article1, words1, -1);//提取文章关键词
jieba.extractor.Extract(article2, words2, -1);
if (words1.empty() || words2.empty()) {//判断得到的关键词数组是否为空数组,是则报错退出
cout << "Text Blank!" << endl;
return 0;
}