第一次个人编程作业
GitHub地址
Github地址
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 40 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 40 |
Development | 开发 | 1010 | 1480 |
· Analysis | · 需求分析 (包括学习新技术) | 180 | 610 |
· Design Spec | · 生成设计文档 | 20 | 25 |
· Design Review | · 设计复审 | 30 | 15 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
· Design | · 具体设计 | 150 | 150 |
· Coding | · 具体编码 | 350 | 500 |
· Code Review | · 代码复审 | 100 | 50 |
. Test | · 测试(自我测试,修改代码,提交修改 | 150 | 100 |
Reporting | 报告 | 75 | 120 |
· Test Repor | · 测试报告 | 5 | 10 |
· Size Measurement | · 计算工作量 | 15 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 50 | 50 |
· 合计 | 1115 | 1640 |
解题思路
思考过程
一开始没有啥思路,脑海比较空白,一开始想着读字符串读到省就取出省,读到市就取出市 (比较傻憨憨的思路)。后来就翻之前笔记,发现正则表达式是个不错的方法,然后想咋写呢,就去网上搜索了下 java 中国地址匹配,果然让我搜索到了一些东西,果然要善用搜索引擎,然后借鉴了一下代码,就开始着手去写啦。
找资料过程
对于我这个菜鸡,真的看了这个布置作业的博客超级超级多看不懂,然后把不懂的一个个复制到百度一个个研究。
我这段时间用到的资料们
资料地址 | 说明 |
---|---|
匹配地址 | 代码的思路很多是这个给的 |
中国各个地址分类 | 让我研究中国的省市县啥的看看还有那些没匹配上 |
代码质量分析 | 分析代码质量用什么 |
性能分析JProfiler | JProfiler的安装和使用 |
单元测试的理解 | 看了这个大概了解了单元测试 |
Junit的基本使用 | 如何单元测试 |
打包成jar | 如何打包成jar包(没按照助教要求的gradle)当时时间不太够用这个快 |
遇到一些打包问题的处理 | 打包时候遇到的问题有没有找到主清单属性以及找不到依赖包 |
StartUML教程 | 我英文也太菜了把,准备用StartUML画流程图看到一堆英文傻了,去网上看了下教程 |
关于UML | 顺带大致看了UML |
UML流程图 | 一些画流程图的规范 |
gradle解析 | 还是要学的 |
gradle快速入门 |
代码思路
用java编写
1.通过文件输入流读取文件
2.把每个用户的信息(行)从整个文件中分别取出来放入字符串数组
3.遍历数值
3.1用正则表达式提取手机号和名字信息,并且将这些从原字符串数组删除
3.2用正则表达式分出地址信息
4.通过文件输出流传出文件
实现过程
主要的类
类名 | 作用 |
---|---|
Main | 开始类(文件输入输出流,调用Util里的方法) |
Util | 处理姓名手机地址信息 |
UserInfo | 暂时存放一个用户信息 |
TotalInfo | 所有处理后的用户信息合集 |
主要函数
函数名 | 作用 |
---|---|
separateTotalInfo(String totalAddress) | 用来调用处理信息的各个函数 |
getName(String info) | 从信息中得到用户名 |
separateName(String info) | 从信息中删除用户名 |
getPhone(String info) | 从信息中得到手机号 |
separatePhone(String info) | 从信息中删除手机号 |
getAddress(String level,String info) | 从信息中得到成功分段的地址 |
disposeFile(String filePath) | 处理输入的文件流 |
produceJsonFile(TotalInfo totalInfo,String filePath) | 处理输出的文件流 |
关键函数流程图
separateTotalInfo(String totalAddress)的流程图
改进过程
改进思路
我代码其实没怎么改进(因为不知道怎么改,么得思路)
非得说改进的话,本来只能把地址分成五层,后来七层也可以了可以满足分成五层也可以七层
性能分析图
用JProfiler生成的,消耗最大的函数是separateTotalInfo(String totalAddress)
代码说明
关键代码说明
这是把地址分为五层的核心代码(七层和这个同理)
思路就是正则表达式匹配省市县区在取出放入List里
String regex="(?<province>[^省]+自治区|.*?省|.*?行政区)?(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市)?(?<dist>[^县]+县|.+?区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+镇|.+街道)?(?<village>.*)";
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(info);
if(matcher.find()){
province=matcher.group("province");//区配省
addressList.add(province==null?"":province.trim());//取出省
city=matcher.group("city");//区配市
addressList.add(city==null?"":city.trim());//取出市
dist=matcher.group("dist");//匹配县
addressList.add(dist==null?"":dist.trim());//取出县
town=matcher.group("town");//匹配区
addressList.add(town==null?"":town.trim());//取出区
village=matcher.group("village");//取出剩下的
addressList.add(village==null?"":village.trim()); //取出剩下的
}
算法的关键
正则表达式匹配(省市县区街)地址
难度1. 把地址分为五级的
String regex="(?<province>[^省]+自治区|.*?省|.*?行政区)?(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市)?(?<dist>[^县]+县|.+?区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+镇|.+街道)?(?<village>.*)";
难度2. 把地址分为七级的
String regex="(?<province>[^省]+自治区|.*?省|.*?行政区)?(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市)?(?<dist>[^县]+县|.+?区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+镇|.+街道|.+乡|.+县)?(?<village>[^村]+路|.+街|.+巷|.+道|.+段|.+队|.+弄|.+胡同|.+村|.+委会|.+开发区)?(?<number>[^区号]+号)?(?<road>.*)";
难度3. 补全缺省地址(附加题)
没写出来
(其实不太完善,认真脸!)
张三,福建福州闽13599622362侯县上街镇福州大学10#111.
张三我dbq 我没能把你的地址完善出来(;´д`)ゞ是我太菜了
这个我思考了一下估计搞个文件放地址,然后遍历匹配到福建就加个省,匹配到城市就把它的后缀名加上市/自治区(没时间搞了所以没搞 dbq)
没有试过这个思路不知道对不对,如果不对或者哪里不够的希望大佬帮我指出一下,如果有大佬看到了,能不能悄咪咪的和我说一下你的思路,我用的java。
(看到好多大佬用的python,我没学,应该把学python提上日程了)
计算模块部分单元测试
单元测试
用的Junit
部分单元测试代码
@Test
public void testGetAddress1() {
List<String> addressList=new ArrayList<>();
addressList.add("福建省");
addressList.add("泉州市");
addressList.add("南安市");
addressList.add("霞美镇");
addressList.add("美西街");
addressList.add("41号");
addressList.add("青青饭店");
assertEquals(addressList,util.getAddress("2","福建省泉州市南安市霞美镇美西街41号青青饭店"));
}
测试七层地址分割数据是否准确,没有用到很复杂的单元测试代码,因为单元的功能没有很多,我的代码也没有很复杂
测试覆盖率
ps:那个com.view的AddressView是用swing写的界面函数,一开始是打算有界面输入混乱的地址,然后还有一个界面提醒整理好的地址(因为觉得这样可读性比较高,虽然java的swing很老啦现在也不用啦,但是当时想的是做个界面输入输出就不是黑框框啦)后来助教要求在控制台输入,所以界面就没有用啦(但是鉴于我幸苦写出来的,所以没有删除,我必须把我写的界面拿出来遛遛,很丑哈哈哈,但是劳动成果嘛)
至于那个test文件是用来放单元测试的
Code Quality Analysis
用的findBugs
计算模块的异常处理
java中如果要进行异常处理,可以使用:try、catch、finally关键字
但我目前只会printStackTrace()输出完整的异常信息,还不会修改异常信息的提示
(对不起 我太菜了
悄咪咪说能少扣点分么)
学习心得
我看到博客的一瞬间心情复杂,我是谁我在哪,360°旋转懵逼(ノ`Д)ノ
然后就是慢慢百度学习的过程,果然是善用搜索呀
虽然我代码写的一点也不好,但是我真的用了超级多的时间,零散的时间我都忽略了,我太菜了,中秋假期我都没有出门,就是坐在家里写代码,我作业从周二写到现在(我很多不会,所以写了这么久),好多亲戚都对我大学还有作业吃惊,(夸我认真学习emmm受之有愧,认真学习的学霸们才不会像我这样啥都不会呢)
单元测试,代码质量分析,分支覆盖率,打包。。。。。。我都不会 (我tcl)
这个中秋好幸苦,学的也好多,我想休息一下(我最近都快一点睡的)
可爱的小兔子结尾 今晚可以早睡了