这个作业属于哪个课程 | 软件工程课程 |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | github应用 json文件解析 提高整体软工实践能力 |
学号 | 031802534 |
目录
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
Estimate | 估计这个任务需要多少时间 | 600 | 900 |
Development | 开发 | ||
Analysis | 需求分析 (包括学习新技术) | 120 | 240 |
Design Spec | 生成设计文档 | 20 | 30 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 30 |
Design | 具体设计 | 60 | 120 |
Coding | 具体编码 | 60 | 120 |
Code Review | 代码复审 | 30 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | ||
Test Report | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 25 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
Total | 合计 | 545 | 830 |
解题思路
写在前面
- 看到题面后,首先确定自己想使用的语言。本来是只选择了更为熟悉的C++完成作业,后发现许多同学都是使用python,我认为还是需要对python有更深入的学习和了解,这样也能够方便未来的组队作业和团队作业,加上考虑到可以两个代码进行相互佐证对比,因此又选择了python来编程。因此共有两种语言写法。但最终因为时间有限以及VS下c++编程遇到的一定困难,代码提交以python为主,C++仅记录在博客中。
- 分析下,整个作业可分成几部分:命令行参数分析、json解析、初始化数据处理以及存储方式、询问处理。
C++
- json解析:由于考虑到C++对json提供解析的库的使用我并不熟练,先进行了一定的学习。在比较了使用库和手写json字符串解析的复杂度后决定直接手写字符串解析。
- 命令行参数分析:通过main函数读入和处理命令行参数,并根据不同进行转跳。
- 初始化数据处理及存储:查询了map、unordered_map以及它们的二维三维存储提取效率,并对四种事件对应的json格式分析后,选择将关键词通过字符'+'拼接,通过三个unordered_map分别存储三种询问,在所有数据处理后导出到三个对应文件中进行存储。
- 询问处理:通过main提取关键词以及询问类型,转跳对应处理函数。读入对应文件后将关键词拼接并查询输出。
python
- json解析:通过正则表达式对json内的关键词进行存储,加快了索引速度,由班级大佬教授。
- 命令行参数分析:通过函数对命令行参数分析,根据不同进行转跳。
- 初始化数据处理及存储:分别将数据存储在三个文件下。
- 询问处理:根据对应询问调用不同函数,提取正则表达式并根据题意输出。
设计实现过程
代码组织
- 总体分成五个部分,主函数main,处理初始化Init,三个处理三种询问分别对应的函数。通过主函数内对命令行的分析进行转跳。
- 根据函数内的不同需求有更细致的划分。
流程图
-
C++
-
python
代码截图与说明
- C++
-
json解析
-
命令行参数分析
- python
-
json解析
puttern用于转换正则表达式
-
命令行参数分析
困难与解决
- 对C++和python如何解析json文件完全不会,通过网上查询资料并上手编程后解决。
- VS编译下C++许多的函数比如getcwd freopen全部算作危险函数不能使用,通过学习新的可在VS编译下通过的函数解决。
- C++重定向输出时,如果输出语句换行用"\n"进行换行,会导致本应输入在前一个文件的东西跑到第二个文件去。经过调试和测试发现将"\n"换成endl的换行就没有问题了。
(想不懂为啥) - 对C++文件路径取用不熟,经过对应学习后解决。
- 没有调整好VS编译环境,导致代码提交到github时各种build失败,配置并调试后成功build。
- 单元测试和性能测试从来没接触过,也是临时在网络上查询学习,但感觉C++的单元测试着实有点难顶,时间上感觉来不太急,因此把这部分放在python上。但我不确定我查到的资料是不是对的,就先硬着头皮冲了。
迭代更新与优化
C++
- C++代码分成两代,第一代数据存储选择先将所有的关键词字符串放入一个vector中进行排序离散化成数字编号,通过数字编号进行数组储存事件次数。这种做法虽然在访问调用上是O(1),但查询访问从来不是这次任务花费时间的地方,主要的时间复杂度在初始化的数据处理当中。而这种做法需要访问两次文件内存,并进行了离散化排序,时间复杂度过高,只是作为参考对照后一代代码的答案正确与否。
- 第二代代码中,第一个改变的想法是数据存储方式,选择unordered_map作为存储容器,以实现存储和访问都是常数级别
(虽然这个常数不小),此外,本想多补上多线程处理多个文件下的情况,但无奈技术不到家,代码调试失败了。 - 后一种写法在时间上比之前一种降低了50%以上,但真正在处理多个文件情况时还是偏慢。最直观的感受还是手写字符串解析确实挺快的。
python
-
初代的python代码参考了助教给出的示例代码,由于对自己python能力的不自信,选择先能够写出满足条件的代码,不考虑时间复杂度。因此第一代代码想法较为直接,将关键词提取后拼接成字符串,采用map进行映射
(与C++的想法一致,只是不确定是否有类似于C++的unordered_map的函数),操作都是最为基础的。没有经过过多的优化。 -
第二代代码考虑到了两个地方的优化:一是多文件读取下采用多线程的写法,二是在与同学的交流和讨论下,学习到的数据转正则表达式写法,以提高效率。这两种优化写法确实提高了代码的效率。
单元测试截图和描述
单元测试代码
-
代码
-
运行结果
单元测试覆盖率
代码规范的链接
总结
代码方面
C++
- 对VS环境下编写C++代码有了更为深入的了解,知道了VS与常用的dev之间的不同之处。
- 了解了C++文件路径方面的知识,不再像之前只会个freopen。
- 锻炼了自己字符串模拟的能力
(大概?毕竟写了个字符串解析)。 - 对C++处理json文件和命令行调用有了一定学习,补全了对应知识盲区。
- 对
(没有实现的)多线程和单元测试有了一定的了解。
python
- 本身自己python水平就不算很好,这次任务是一次很好的锻炼。
- 对python处理json文件和命令行调用有了一定学习,补全了对应知识盲区。
- 对python多线程和单元测试有了一定的了解。
- 学习到了正则表达式的妙用。
其他
- 对github的基本操作有了更多了解。
- 对三种语言的规范有了一定的学习和了解。
- 通过不断厚脸皮向班里dalao求救,脸皮厚度有了一定的增加。
- 深刻感受到知识面的不足,许多软工方面的知识都不会,本来以为自己只会写代码,现在发现代码都不会写了。
- 学习!