第一次个人编程作业
Github项目地址:
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 20 |
Development | 开发 | 2280 | 2565 |
· Analysis | · 需求分析 (包括学习新技术) | 1000 | 1220 |
· Design Spec | · 生成设计文档 | 30 | 40 |
· Design Review | · 设计复审 | 10 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定或选择合适的规范) | 10 | 10 |
· Design | · 具体设计 | 10 | 15 |
· Coding | · 具体编码 | 1000 | 1040 |
· Code Review | · 代码复审 | 20 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 200 | 230 |
Reporting | 报告 | 40 | 35 |
· Test Report | · 测试报告 | 20 | 10 |
· Size Measurement | · 计算工作量 | 10 | 15 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出改进计划 | 10 | 10 |
· 合计 | 2360 | 2670 |
解题思路:
老实讲,刚拿到题目的时候,我的心情是崩溃的。在c++已经忘得差不多要用c++打好像也等于重新学的情况下,偶然听闻大佬惊呼:“这道题用java简单!”我就想,既然大佬都说简单了,那我等菜鸡也不至于做
不出来吧,于是乎,我就一头扎进了学习java这个新知识的海洋里励志当一个努力的人(当事人表示现在就是后悔啊)。既然要学习,特别是像我等从零开始的人,第一件事就是找网课速成,幸运的是,在舍友(啊我要表白我超nice的舍友啊~)的推荐下找到了一个不错的网课。可以说这三季看下来,确实掌握了不少知识点,老师讲的很清楚,然后也相对应做了不少笔记。不过呢所谓速成不就是缺少实战经验,所以虽然我理论知识记了好多笔记,实际上敲起代码却不知从何下手。于是乎,再次感到自己不行的我又一次义无反顾的扎进~~ 差点 ~~已经把我溺死的java的海洋:我到实验室拿了一本厚到从二楼扔下去都可以砸死人的《java疯狂讲义》开始粗略浏览(主要就是先前听闻大佬们说会用到正则啊json啊的内容然后想找看看书里有没有比较详细的讲解)。
思考过程呢就是当我拿到题目感觉很难的时候,就想着那我肯定是不能一下子奢望自己都能过的,还是从简单的开始一点一点点尽量多捞点分数。于是我先放弃看起来最难的输入输出(是的因为我太菜了所以感觉输入输出好难啊),先把名字和手机号码提取出来,然后再用最简单的方法把地址提取出来(先忽略掉没有省市的情况),最后再去纠结输入输出,然后再一步步的完善地址的提取函数。
实现过程设计:
正可谓梦想总是丰满的现实总是骨感的,当我开始拿到题目的时候,我是这么幻想的。
类与函数(以及两者之间的关系):
- 定义一个perSon类
- 用来控制文件的输入
- 用来控制字符串的循环操作
- 用来控制字符串的输出
- 定义一个addaddRess类
- 函数1:Name:
- 用来将名字分离出字符串(虽然后来实际操作中感觉这点并不需要用到函数)
- 函数2:Telphone:
- 用来将连续的11个数字从字符串分离出来成为手机号码(是的实际操做中这个也并不需要函数)
- 函数3:Address1:
- 先十分粗略的根据字符串中的“省,市”等关键字去把地址给摘出来(
ok,这就是菜鸡的plan b,想着我做出这么一些总得给我点分吧)- 函数4:Address2:
- 去考虑第二个案例所会出现的如果省略了“省,市”等关键字的情况去把地址摘出来
- 函数5:Address3:
- 在Address2的基础上考虑到附加题中的内容
关键Address函数流程图
算法的关键与独到之处
1.文件的输入与输出:
这次的题目要求我们用文件输入并且输出为文件形式。老实讲这是我刚开始尝试的时候的一个难题。所以我当时的解题思路就是在将字符串处理完之后再来纠结输入和输出。我认为这种解法对于一些跟我一样基础比较薄弱的同学是比较高效的,一步一步来能有利于后面的修改。然后将文件中的信息用字符串一行一行的读入,其中需要用到字符串数组。
2.手机号码与地址的摘取:
手机号码与地址的摘取的算法最重要的是要用到正则表达式。
首先在比较简单的手机号码方面,通过\d{11}将连续出现的11个数字作为手机号码从字符串中提取出来。然后在地址方面,Address1比较简单的方法时是先用"(?[省]+自治区|.*?省|.*?行政区|)(?<city>[市]+自治州|.?地区|.?行政单位|.+盟|市辖区|.?市|)(? 进行最简单的将五级的地址给剥离出来。然后在后面的Address函数中再用[^县]+县|.+?区|.+市|.+旗|.+海域|.+岛)?(? 街|.路|.巷)?(?.+镇|.+街道)?(? . [\d]+号|)?(? .*)" 暴力解法把一些特殊的情况比如有的没有写省市县啊还有直辖市的情况给一步步改进过来。
接口性能改进:
在改进计算模块性能上花费了一天的时间,我的改进思路主要是在地址的摘取方面。首先是根据正则表达式先把一些较为简单的(如有明确的“省市区”区分的并且没有直辖市的地址)先五层区分出来,然后就是将有直辖市的“北京,上海,天津,重庆”给if出来,最后就是针对那些省略了“省市区”等区分词的地址的函数,然后可以的话进行七级分割。其中消耗最大的函数是Adress函数。
性能分析图:
部分代码说明
解题思路在上面👆我就不重复啦~
关于输入的核心代码:
String[] strArray=new String[20000];
int i=0;
InputStream is = new FileInputStream("/Users/ann/eclipse-workspace/FindPerson/src/com/Person/Homework1In.txt");
String line; // 用来保存每行读取的内容
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
line = reader.readLine(); // 读取第一行
strArray[i]=line;
i++;
while (line != null) { // 如果 line 为空说明读完了
line = reader.readLine(); // 读取下一行
strArray[i]=line;
i++;
}
reader.close();
is.close();
关于姓名和手机的摘取:
String str=new String();
for(int j=0;j<i-1;j++) {
str=strArray[j];
String[] str1=str.split(",");
String name=str1[0];
Map m11=new HashMap();
m11.put("\r\n"+"\"姓名\"","\""+name+"\"");
str=str.replace(name,"");
str=str.replace(",","");
str=str.replace(".","");
String Telphone=null;
String TelephoneNumber="\\d{11}";
Matcher a = Pattern.compile(TelephoneNumber).matcher(str);
while (a.find()){
Telphone=a.group();
str=str.replace(Telphone,"");
}
m11.put("\r\n"+"\"手机\"","\""+Telphone+"\"");
单元测试:
- 单元测试数据的构造思路:
由于我是用整个主函数作为测试函数的,所以我建立了一个test的文件,然后主要是为了测试Address 的判断摘取函数是否能够覆盖掉一些比较偏门的测试数据,比如“云南迪庆藏族自治州香格里拉市”等。- 测试覆盖率截图以及部分代码:
异常处理:
第一个异常目标:
第一个异常的处理是输入时缺少名字的分割处理,
当时的输出案例如下:
从输出的截图中可以看出,名字的缺失导致整个字符都被当成姓名输出了。第二个异常目标:
第一个异常的处理是输入时手机号码未按规定输入11位的分割处理,
当时的输出案例如下:
从输出的截图中可以看出,由于手机号码未按规定书写导致整个字符串被当成姓名输出。
心路历程:
因为这个个人编程作业,在短时间内自学了java,虽然说这种短时间高强度的学习很累,但是也收获了很多。虽然只是粗略的学习了java,但是好歹也是多熟悉了一门语言,然后在打代码的过程中遇到了很多的问题并且很努力请教别人努力的把问题给解决了。虽然说这次个人编程作业有好多好多不足,可能也没按照规则去输入输出,但是我已经很努力的在所学的知识里做到最好了。至于结果......有收获就好了。