第一次个人编程作业

[项目地址](https://github.com/chen739917425/SoftwareWork/tree/master/031702334/addressbook) ## PSP PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) :-: | :-: | :-: | :-: Planning | 计划 | 60 | 60 | Estimate | 估计这个任务需要多少时间 | 20 | 20 | Development | 开发 |300| 250| Analysis | 需求分析 (包括学习新技术) |180 | 120| Design Spec | 生成设计文档 |90 | 60| Design Review | 设计复审 |90 | 30| Coding Standard | 代码规范 (为目前的开发制定合适的规范) |30 | 10| Design | 具体设计 |60 | 120| Coding | 具体编码 |300| 600| Code Review | 代码复审 |30 | 10| Test | 测试(自我测试,修改代码,提交修改) |60 | 20| Reporting Standard | 报告 |60 |40 | Test Repor | 测试报告 |60 |40 | Size Measurement | 计算工作量 |20 |10| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 |30 | 20| . | 合计 |1330 |2570 | ## 设计与实现 ### 组织结构 结构如下: ![](https://img2018.cnblogs.com/blog/1330878/201909/1330878-20190917222855638-922636501.png) 主要包含: * 两个unordered_map,Province和Municipality,存储省、市信息和直辖市信息 * 两个编码转换的函数,负责UTF-8和Unicode的相互转化 * 一个格式拼接函数,负责将Address解析出的结果拼接成一个json格式数组 * 一个类Address,主要有地址解析、格式转化两大功能 * 其中地址解析功能又分出若干函数,来实现逐级解析,结构如下 ![](https://img2018.cnblogs.com/blog/1330878/201909/1330878-20190917223947074-2125080676.png)

类与函数的关系

以流程图的形式大致描述处理思路

有关算法

* 文本匹配:说实话,对于这样小量的文本匹配工作,朴素的匹配算法已经足够(KMP之类的高效匹配算法由于其需要额外的空间开销和预处理时间,并不能体现出效率优势,徒增编程复杂度),因此我选择直接调用string中的find函数进行匹配。 * 地名检索并提取:由于文本匹配可优化的幅度极其有限,因此我主要在地名的检索上做一些工作。我将我国所有省、市两级的信息爬下来,以文本文件的形式存在本地。在类初始化时将其读入,用哈希表```unordered_map```储存,```key```为省份,```value```为该省份下所有市组成的```vector```。通过枚举所有省份来匹配地址中的省份,匹配完省份后,就可以枚举该省份下的市行政区,继续匹配市级。 * 独到之处:并没有什么独到之处,硬要说的话,大概就是我是少数用C++写这个项目的,踩了无数中文编码上的坑。还有我是用本地存表的形式来辅助地址解析的,核心逻辑也都是手写的,没有调用现成的一些接口,因此对于一些奇怪的情况难以正确解析。

性能改进

  • 原先对于省市的检索,是通过遍历整个文本文件,对于文本中的每个省(或市)都去查找能否匹配上输入地址,因此是省市数量*文本匹配的复杂度。
  • 考虑用哈希表unordered_map来存储省市信息,提高检索效率,对于确定省份的情况,从键值为该省份的vector中寻找市级行政区,而不需要全部枚举
  • 性能分析图如下:



    可以从上图看出,时间的开销主要在初始化上,也就是从文本文件中读入省、市信息并储存上。

单元测试

测试了一些比较容易错误解析的情况,如:
input:

1!洪嘹,广东佛山市高明区更15198460545合镇广明高速公路界村林场.
1!娄伤囚,13592755594浙江省杭州市所前镇袄庄陈村工业园区5号楼.
2!乐愿,山东省潍坊安丘15223742753市兴安街道南关头巷南关头幼儿园.
2!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层.
1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.
2!王五,福建省福州市鼓楼18960221533区五一北路123号福州鼓楼医院.
3!小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.
1!小陈,广东省东莞市凤岗13965231525镇凤平路13号.
2!东海黄,上海市吊人区北大街89号垃圾堆.

output:

[{"姓名":"洪嘹","手机":"15198460545","地址":["广东省","佛山市","高明区","更合镇","广明高速公路界村林场"]},{"姓名":"娄伤囚","手机":"13592755594","地址":["浙江省","杭州市","所前镇袄庄陈村工业园区","","5号楼"]},{"姓名":"乐愿","手机":"15223742753","地址":["山东省","潍坊市","安丘市","兴安街道","南关头巷","","南关头幼儿园"]},{"姓名":"李四","手机":"13756899511","地址":["福建省","福州市","鼓楼区","鼓西街道","湖滨路","110号","湖滨大厦一层"]},{"姓名":"张三","手机":"13599622362","地址":["福建省","福州市","闽侯县","上街镇","福州大学10#111"]},{"姓名":"王五","手机":"18960221533","地址":["福建省","福州市","鼓楼区","","五一北路","123号","福州鼓楼医院"]},{"姓名":"小美","手机":"15822153326","地址":["北京","北京市","东城区","","交道口东大街","1号","北京市东城区人民法院"]},{"姓名":"小陈","手机":"13965231525","地址":["广东省","东莞市","","凤岗镇","凤平路13号"]},{"姓名":"东海黄","手机":"","地址":["上海","上海市","吊人区","","北大街","89号","垃圾堆"]}]

可以发现对于第二条,实际上是缺失了第三级地址,但我误把工业园区当作了第三级,对此.......不借助成熟接口且不存入一张信息量巨大的表的话,我真的没办法了。

异常处理

对于异常处理,主要注意力放在转码和文本操作这些容易出事的地方。如 ![](https://img2018.cnblogs.com/blog/1330878/201909/1330878-20190918011433281-2068157145.png) 对于转码失败的情况,输出错误内容,退出程序 ![](https://img2018.cnblogs.com/blog/1330878/201909/1330878-20190918011640194-1343109951.png) 如果在评测时没有成功打开我的文本文件,则解析无法进行,输出提示,退出程序。
posted @ 2019-09-16 02:15  __orange  阅读(388)  评论(4编辑  收藏  举报