1、github项目地址
2、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时 (分钟) |
实际耗时 (分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 1900 | 2410 |
· Analysis | · 需求分析 (包括学习新技术) | 1200 | 1000 |
· Design | · 生成设计文档 | 30 | 20 |
· Design Review | · 设计复审 | 20 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定或选择合适的规范) | 10 | 10 |
· Design | · 具体设计 | 60 | 40 |
· Coding | · 具体编码 | 360 | 1200 |
· Code Review | · 代码复审 | 100 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 100 |
Reporting | 报告 | 110 | 35 |
· Test Report | · 测试报告 | 60 | 10 |
· Size Measurement | · 计算工作量 | 10 | 5 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出改进计划 | 40 | 20 |
· 合计 | 2040 | 2475 |
3、计算模块接口的设计与实现过程
选择编程语言
Java
思考
刚看到这个题目的时候很懵,不知道如何下手。需要学习的新技术也很多,在查找了相关资料后,我发现用java实现比较容易,于是java的学习也添进了计划中。接下来花大量时间学习了很多教程。浏览了网上关于java实现地址分割的文章后,我从里面的List使用想到了方向,设计好如下所示的解题思路和设计后,就开始了编码。
待学习:java语法、json文件格式、code quality analysis、studio profiling tools、单元测试、使用插件查看覆盖率等指标、上传代码到github......
代码组织
(1)类和函数
类名 | 属性 | 函数名 |
---|---|---|
Main | main | |
partitionI | name,telephone,address | getName,getTelephone |
partition1 (作为partitionI的子类) |
city,county,town,detail,detailstreet,detailnum | addressResolution1, addressResolution2,show |
(2)解题思路
- 先从键盘输入一条数据
- 取名字
- 取号码
- 分割地址
- 转json格式输出
- 改成读写文件形式
(3)实现过程
- 在main函数中读入文件,利用字符串数组处理每一行的信息,用一个function标志区分实现哪一功能(五级or七级地址)。
- 编写getName函数获取name,编写getTelephone函数获取telephone。使用String相关函数和for循环可以实现定位和提取。
- 修改字符串使之只剩地址信息,在addressResolution1函数和addressResolution2函数中利用正则表达式给address赋值
- 在show函数中利用LinkedHashMap分别给"姓名"、"手机"、"地址"匹配name,telephone,address,最后装到List中
- 将List转换为json格式输出到文件中
算法关键和独到之处
- 提取和定位字符串用到split、substring、indexOf、charAt等String类的函数,用for循环找到连续的11个数字定位手机号。
- 利用正则表达式分割地址字符串,并匹配。
- address的类型是ArrayList;匹配元素用到LinkedHashMap。
项目关键代码
String regex="(?[^省]+自治区|.*?省|.*?行政区|.*?市)(?[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)(?[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)?(?[^区]+区|.+镇|.+乡|.+街道)?(?.[^路]+路|.+道|.+街|.+巷|.+胡同|.+里弄|.+弄)?(?.[^号]+号)?(?.*)";
Matcher m=Pattern.compile(regex).matcher(ogdata);
JSONArray json = new JSONArray(table);
m.writeFile(json.toString());
4、计算模块接口部分的性能改进
改进思路
在编码过程中遇到很多bug,主要通过查找资料解决。
性能分析图
5、计算模块部分单元测试展示
测试的函数和构造测试数据的思路
- test1测试getName,test2测试getTelephone
- test3~test9测试不同情况下的地址分割,选择五级或七级的地址分割,结合所给测试样例和网上查找的地名测试
代码
@Test
public void test1() {
partition1 person = new partition1();
assertTrue(person.getName(4,"1!李四,福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层").equals("李四"));
}
@Test
public void test2() {
partition1 person = new partition1();
assertTrue(person.getTelephone(16,"福建省福州13756899511市鼓楼区鼓西街道湖滨路110号湖滨大厦一层").equals("13756899511"));
}
@Test
public void test3() {
partition1 person = new partition1();
person.addressResolution1("福建省福州市鼓楼区鼓西街道湖滨路110号湖滨大厦一层");
ArrayList answer =new ArrayList();
answer.add("福建省");answer.add("福州市");answer.add("鼓楼区");answer.add("鼓西街道");answer.add("湖滨路110号湖滨大厦一层");
boolean test = true;
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
@Test
public void test4() {
partition1 person = new partition1();
person.addressResolution1("福建省福州市鼓楼区五一北路123号福州鼓楼医院");
ArrayList answer =new ArrayList();
answer.add("福建省");answer.add("福州市");answer.add("鼓楼区");answer.add("");answer.add("五一北路123号福州鼓楼医院");
boolean test = true;
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
@Test
public void test5() {
partition1 person = new partition1();
person.addressResolution2("广东省东莞市凤岗镇凤平路13号");
ArrayList answer =new ArrayList();
answer.add("广东省");answer.add("东莞市");answer.add("");answer.add("凤岗镇");answer.add("凤平路");answer.add("13号");
boolean test = true;
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
@Test
public void test6() {
partition1 person = new partition1();
person.addressResolution1("北京市东城区交道口东大街1号北京市东城区人民法院");
ArrayList answer =new ArrayList();
answer.add("北京");answer.add("北京市");answer.add("东城区");answer.add("");answer.add("交道口东大街1号北京市东城区人民法院");
boolean test = true;
System.out.println(person.address);
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
@Test
public void test7() {
partition1 person = new partition1();
person.addressResolution2("福建省福州市鼓楼区鼓西街道湖滨路110号湖滨大厦一层");
ArrayList answer =new ArrayList();
answer.add("福建省");answer.add("福州市");answer.add("鼓楼区");answer.add("鼓西街道");answer.add("湖滨路");answer.add("110号");answer.add("湖滨大厦一层");
boolean test = true;
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
@Test
public void test8() {
partition1 person = new partition1();
person.addressResolution2("江苏省苏州市姑苏区寒山寺弄24号");
ArrayList answer =new ArrayList();
answer.add("江苏省");answer.add("苏州市");answer.add("姑苏区");answer.add("");answer.add("寒山寺弄");answer.add("24号");answer.add("");
boolean test = true;
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
@Test
public void test9() {
partition1 person = new partition1();
person.addressResolution2("福建省宁德市东侨经济开发区东湖路19号");
ArrayList answer =new ArrayList();
answer.add("福建省");answer.add("宁德市");answer.add("东侨经济开发区");answer.add("");answer.add("东湖路");answer.add("19号");answer.add("");
System.out.println(person.address);
boolean test = true;
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
@Test
public void test10() {
partition1 person = new partition1();
person.addressResolution1("福建福州闽侯县上街镇福州大学10#111");
ArrayList answer =new ArrayList();
answer.add("福建省");answer.add("福州市");answer.add("闽侯县");answer.add("上街镇");answer.add("福州大学10#111");
System.out.println(person.address);
boolean test = true;
for (int j = 0; j < answer.size(); j++)
{
String obj =answer.get(j);
if (!person.address.contains(obj))
{
test=false;
}
}
assertTrue(test);
}
测试覆盖率和正确率截图
有一些缺省的地址信息还无法做到正确的匹配。
6、计算模块部分异常处理说明
对输入输出做了异常处理,防止输入非法文件。
7、心路历程与收获
一开始,我连题目都没看懂,对开始完成这道题目完全没有信心和思路。经过两天的熟悉,大概知道了学习的方向。因为没学过java,开始疯狂学习有关java的入门知识。确定思路后,我进行了简单的设计就开始了编码,这也是我做的不足的地方,导致分类和函数还是有点乱,实现方法也不佳。由于编程能力的薄弱和语法的陌生,编码过程频频出错,需要依靠大量的搜索和运行输出发现问题。经过三天的编码和纠错,终于实现了一部分题目要求。这一周,我的最大收获是学会细化任务,将看似困难的任务分解为貌似可以做到的小任务。此外,我学会了很多新的技术,对整个开发流程有了一定的熟悉。需要改进的地方是今后要加强编程练习,并且要学会设计流程更规范化,还要接触很多需要学习的新知识。
第一次个人编程作业几乎填满了我这一周所有的空闲时间,还开启了熬夜模式,过程很累,但也学到了很多。(没有什么是一个熬夜解决不了的,如果有,就来六个!)