这个作业属于哪个课程 软件工程课程
这个作业要求在哪里 作业要求
这个作业的目标 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的函数),操作都是最为基础的。没有经过过多的优化。

  • 第二代代码考虑到了两个地方的优化:一是多文件读取下采用多线程的写法,二是在与同学的交流和讨论下,学习到的数据转正则表达式写法,以提高效率。这两种优化写法确实提高了代码的效率。

单元测试截图和描述

单元测试代码

  • 代码

  • 运行结果

单元测试覆盖率

代码规范的链接

python代码规范

总结

代码方面

C++

  • 对VS环境下编写C++代码有了更为深入的了解,知道了VS与常用的dev之间的不同之处。
  • 了解了C++文件路径方面的知识,不再像之前只会个freopen。
  • 锻炼了自己字符串模拟的能力(大概?毕竟写了个字符串解析)
  • 对C++处理json文件和命令行调用有了一定学习,补全了对应知识盲区。
  • (没有实现的)多线程和单元测试有了一定的了解。

python

  • 本身自己python水平就不算很好,这次任务是一次很好的锻炼。
  • 对python处理json文件和命令行调用有了一定学习,补全了对应知识盲区。
  • 对python多线程和单元测试有了一定的了解。
  • 学习到了正则表达式的妙用。

其他

  • 对github的基本操作有了更多了解。
  • 对三种语言的规范有了一定的学习和了解。
  • 通过不断厚脸皮向班里dalao求救,脸皮厚度有了一定的增加。
  • 深刻感受到知识面的不足,许多软工方面的知识都不会,本来以为自己只会写代码,现在发现代码都不会写了。
  • 学习!
posted on 2020-09-16 22:53  edwardwsb  阅读(111)  评论(1编辑  收藏  举报