第一次编程作业

个人编程作业

一,GitHub链接

https://github.com/Lu-Huan/031702513.git

二,PSP表格

过程 预估耗时(分钟) 实际耗时(分钟)
计划 30 60
估计任务时间 30 60
开发 1200 1560
需求分析 (包括学习新技术) 60 120
生成设计文档 30 30
设计复审 60 60
代码规范 (为目前的开发制定合适的规范) 60 30
具体设计 120 240
具体编码 720 780
代码复审 30 60
测试(自我测试,修改代码,提交修改) 120 240
报告 60 60
测试报告 30 30
计算工作量 15 15
事后总结, 并提出过程改进计划 15 15
合计 1290 1680

三,计算模块接口的设计与实现过程

1.获取地图数据

从GitHub上拉取了中国的行政区数据 https://github.com/artiely/Administrative-divisions-of-China
东西挺多的,我只拿了其中的一份json数据,包括了省份、城市、区县、乡镇,去掉其中的编码后简洁了不少。
第一次编程作业_第1张图片

2.获取json工具

又去GitHub上找到了一个json工具库 https://github.com/open-source-parsers/jsoncpp/
前期耗时就在这个库上(各种无法编译),捣鼓一番后在VS里把jsoncpp的源码编译成了lib静态库,加入项目里就可以方便的利用这个工具读写json了

3.地址分割

提取姓名和手机号码都是特别容易的,难度主要在于各级地址的分割,其中又会遇到缺失问题,
利用json库读取地图数据后生成高度为4的字典树,这样就非常方便的进行地址匹配了

graph LR
根-->省/直辖市
省/直辖市-->市/州
市/州-->县/区
县/区-->乡/镇/街道

主要的地址寻找算法:

模糊搜索:寻找各级地址的后缀的特征,拿到测试值

精确匹配:把模糊搜索的测试值到字典树里判断是否存在该key(最后一级判断否有value),如果存在,则说明该级的地址寻找成功

某一级缺失:寻找下一级可能的值,在上一级中进行遍历查找,如果存在则可以找到缺失的地址。如:福建省闽侯县,当发现找不到市级行政区时,模糊搜索到下一级地址:闽侯县,在已经匹配到的福建省这颗树中搜索,发现“福建省”的成员“福州市”中存在“闽侯县”这个值,则找到了缺失的市级行政区“福州市”

4.函数

void GbkToUtf8() //转码
void Utf8ToGbk() //转码
void ReadMapOfChina() //读取中国行政区的数据

void GetName()//获取名字
void GetPhone()//获取电话号码
Json::Value GetAddress()//获取地址,返回json::Value

int FindWord()//寻找一个或多个字符
bool IsNum()//判断是否是数字
bool IsChinese()//判断是否是汉字
bool IsMunicipality()//判断是否是直辖市

string ToSerch()//中间一级缺失搜寻

四.计算模块接口部分的性能改进

为了提高模糊搜索的精度我对全国地图数据进行了分析,得到了一些基本信息(其中乡/镇后缀词种类很多,已经做了筛选)

[
  "市级后缀词数量",
  {
    "盟": 3,
    "区": 81,
    "市": 294,
    "县": 12,
    "直辖县级行政区划": 4,
    "自治州": 30
  },
  "县级后缀词数量",
  {
    "区": 447,
    "市": 164,
    "县": 857
  },
  "乡镇级后缀词数量",
  {
    "开发区": 128,
    "街道": 2876,
    "林场": 121,
    "农场": 185,
    "乡": 5804,
    "镇": 11345
  }
]

地图数据开始只有一份,读取的时候生成树的过程较慢经常出现null的情况,将地图数据分割成两份后解决问题

数据分析发现JsonValue的读取消耗是最大的,由于匹配过程中不断的与字典树匹配所以消耗较大
第一次编程作业_第2张图片

五.计算模块部分单元测试展示

测试的一千多条样例结果
第一次编程作业_第3张图片

部分测试样例展示

2!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层.
1!张三,福建福州闽13599622362侯县上街镇福州大学10#111.
2!王五,福建省福州市鼓楼18960221533区五一北路123号福州鼓楼医院.
3!小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.
1!小陈,广东省东莞市凤岗13965231525镇凤平路13号.
[
   {
      "地址" : ["福建省","福州市","鼓楼区","鼓西街道","湖滨路","110号","湖滨大厦一层"],
      "手机" : "13756899511",
      "姓名" : "李四"
   },
   {
      "地址" : [ "福建省", "福州市", "闽侯县", "上街镇", "福州大学10#111" ],
      "手机" : "13599622362",
      "姓名" : "张三"
   },
   {
      "地址" : [ "福建省", "福州市", "鼓楼区", "", "五一北路", "123号", "福州鼓楼医院" ],
      "手机" : "18960221533",
      "姓名" : "王五"
   },
   {
      "地址" : ["北京","北京市","东城区","","交道口东大街","1号","北京市东城区人民法院" ],
      "手机" : "15822153326",
      "姓名" : "小美"
   },
   {
      "地址" : [ "广东省", "东莞市", "", "凤岗镇", "凤平路13号" ],
      "手机" : "13965231525",
      "姓名" : "小陈"
   }
]

六.计算模块部分异常处理说明

如果找不到指定后缀将返回0

如果一些输入不合法将返回空字符串

如果某级缺失,并且也搜索不到,后面的搜索将不会开始

即使输入格式合法,但地名不合法,将判定缺失。如:输入“一二省”,由于数据表里不存在这个省,将判断省缺失。

七,总结

1.对于后续的改进,难度3里我只寻找了单一级缺失,对于多级缺失,还未做,如果同时缺失了省份和市区,目前没写查找。

2.由于数据量大小的问题,我的地图数据只到了第四级,对于难度三的缺失四级数据补全将无法做到,难度三的很多测试失败也大都是因为这个

你可能感兴趣的:(第一次编程作业)