第一次个人编程作业

一.Github项目地址(1分)

https://github.com/fzu-vera/031702505

二.psp表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 30
Estimate · 估计这个任务需要多少时间 30 30
Development 开发 120 120
Analysis · 需求分析 (包括学习新技术) 300 420
Design Spec · 生成设计文档 90 60
Design Review · 设计复审 30 30
Coding Standard · 代码规范 (为目前的开发制定合适的规范) 60 30
Design · 具体设计 120 60
Coding · 具体编码 300 500
Code Review · 代码复审 60 200
Test · 测试(自我测试,修改代码,提交修改) 120 0
Reporting 报告 60 60
Test Repor · 测试报告 30 0
Size Measurement · 计算工作量 30 60
Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 120 180
· 合计 1500 1780

三.计算机接口的设计和实现过程

1.题目要求分析

    题目的要求是将一份客户地址规范化处理。题目要求我们将地址中的"直辖市/省","直辖市/市","区/县/县级市","街道/镇/乡","详细地址"分离开,最后的地址形式以["直辖市/省","直辖市/市","区/县/县级市","街道/镇/乡","详细地址"]出现。现在,我们所要处理的文件现状是名字用逗号与后面的部分隔开,其余部分全部都混为一体(手机号码一定不会和地址中的数字相邻)。

2.查找资料

    我首先是在csdn网站查找相应的资料,也在书上找了不少相关的例题,发现相关问题的解决大部分是Java或者python。c++方面的相关材料相比之下就少了很多。所以在我刚开始用c++写代码遇到问题之后,我开始试着利用Java用正则来i二觉问题,但是在具体的代码实现过程中,我发现我遇到的问题越来越多,并且因为对Java压根不熟悉,所以很多地方会有大大小小的问题却解决不了。所以到最后,我还是选择了c++来实现代码。
    c++对于中文字符的操作,首选是用转码方式,但是因为我前期已经消耗了很多时间,并且转码在短时间内没办法学到位,所以我最后还是选择了用字符串的方法对中文字符操作。c++在对于字符串操作方面还是有比较读懂多资料可以参考的。同时,我从同学那里了解到了,引入地图api能更好地解决地址问题,但是我在查资料过程中发现以我的能力,要做到这一步十分困难,所以最后还是放弃了。最后,我确定了用c++实现代码,查找了许多关于字符串处理的相关资料。

3.解题思路,算法设计

    (1)题目要求是要把所输入的文件按行来执行操作,要求文成输出文件,并以json格式输出。
    (2)题目执行的对象是文本,主要是涉及文件的输入输出,还有对文件的操作。
    (3)遇到这宗切割地址的题目,我的第一反应是用正则,不过因为我个人没接触过Java,对python也仅仅是最基础的了解,所以我最后选择了用c++来解题。用c++解题的话,我是选择用字符串对中文文本进行操作。
    (4)要得到题目所要求的结果,必须对题目所给的条件进行提取切割。其中名字和电话号码都比较好提取,“省”“市”部分因为名字匹配等问题较难处理(输入的数据中的地址部分可能不包括“省”“市”关键词),最后对于县区以及详细地址的提取分割相对来说更加复杂了,需要多找些资料了解。
    (5)思路还算清晰,但是只能解决最简单的问题,还有很多细节问题没有解决的思路。代码实现较为复杂。

4.设计实现过程。(设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?)

    从我的处理思路来看应该函数部分比较重要,首先是文件的处理,读入文件内容,以便后续对文件的操作。其次是文件输出处理,将处理好的内容写入输出文件。代码中会有一个类addr[],用来存储输入的地址信息等等,也用来存入处理后的信息。具体处理字符串是通过find查找函数,还有substr复制函数,erase删除函数。同时也是要按顺序处理,1.处理电话号码部分 2.处理名字部分 3. 处理省份部分 4.处理市级(直辖市/市) 5. 处理县级(区/县/县级市)6.处理详细地址部分。
    具体实现如下:首先,我们可以将文件输入的每一行存为字符串addr[ ].total。因为可以确定名字和后面的部分一定会用逗号隔开,所以可以以逗号为标识符,将名字取出存入名字对应的变量addr[ ].name。然后可以将手机号码的字符子串从字符串addr[ ].total删除。然后就是可以将电话号码从混乱的地址部分分离出来(电话号码为十一位,而且跟地址中的数字不会相邻),将手机号码存入相应的变量addr[ ].number,同样的,可以将字符串addr[ ].total中的手机号码字串删除。之后,可以查询addr[ ].total中含有哪个省份,进而得到省份存入addr[ ].pro,而后将addr[ ].total中的省份字串删除。匹配市级(直辖市/市)时,将直辖市与普通市级分开匹配,匹配后同样删除total中的相应字串。匹配县级(区/县/县级市)时,和匹配省份是相同的操作,匹配完成并记录相应的值之后,将该字串从addr[ ].total中去除,最后字符串total中剩下的就是详细地址了,可以将其复制存入addr[ ].detail中。至此,处理完的信息就都存到类addr[ ]中了。
    关键函数不必画出流程图,因为整体上就是简单的操作流程,按顺序分离出各个部分,按照这个思路写下去就可以了。

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

1.性能改进

    时间:在性能改进这一部分花了大致有一个多小时。
    原做法:在改进程序方面主要是在处理省份这一部分,之前所用的做法有两个缺陷。一个是,因为一开始观察题目不够仔细,没注意到可能会出现给出的地址中没有“省”字,所以一开始的程序是查找“省”字在字符串addr[ ].total中的位置,然后获取省份,进而删除原字符串中的省份相关子串。后来因为注意到了可能会出现给出的地址中没有“省”字的情况。还有一个是,我第一次的做法默认省份都是两个字,之前的做法是在找到“省”字后,往前删除两个文字和删除“省”字,但是我忽略了像“黑龙江省”这样省份名字超过两个字的省份。所以之前的操作会出现较大的失误,所以换了一种想法。
    改进思路:改进之后,是建立了一个包括全国所有省份(不含有“省”字)的数组,在处理省份的问题的时候,遍历一遍下来看字符串addr[ ].total中是否很有相关的省份,有的话就可以确认addr[ ].pro的内容,进而在addr[ ].total中删除。而后,在删除了省份字段的addr[ ].total中查找是否有“省”字,有的话删除addr[ ].total中的“省”字,再继续下一步操作,没有的话,直接进行下一步操作。

2.性能分析图

摘要部分

函数部分

模块部分

3.代码中消耗最大的函数是遍历查询省份的函数。

		string provin[40] = { "河南","河北","北京" ,"天津","山东","山西","黑龙江","吉林","辽宁","浙江","江苏","上海","安徽","江西","湖南","湖北","新疆","云南","贵州","福建","宁夏","西藏","四川","重庆","内蒙古","广西","海南","青海","甘肃","陕西","广东" };

		for (int k = 0; k < 23; k++) {

			one = -5;

			one = flag.find(provin[k]);

			if (one >= 0) {

				addr[j].pro = provin[k];

				cout << addr[j].pro << endl;

			}

			if (one >= 0) {

				break;

			}

		}

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

1.关键代码

    这部分代码主要是按顺序分别查找addr[ ].total中的["直辖市/省","直辖市/市","区/县/县级市","街道/镇/乡","详细地址"]等各个要素,将其复制到其对应的相应变量后,在addr[ ].total删除该字串,一步步操作,最后得到addr[ ].detail。
		one = flag.find(",");

		nam = flag.substr(0, one);//复制逗号之前的名字

		flag.erase(0, one + 1);//删除字符串中的名字和逗号

		addr[j].name = nam;//将名字存入类

		one = 0;

2.函数说明

    这部分主要测试的是erase函数,看erase函数是否能够正确删除字符串中的相应字串,并且不出现错误。

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

    计算模块异常:在处理每一部分的时候,都是将想要的字符串取出来存进相应的变量,然后在addr[ ].total删除相应字串。一开始选用的函数只能从字符串addr[ ].total卡年开始往后删除,如果从中间删除会使删除的那部分变成未知量。
    计算模块异常处理:最后我放起来原来使用的函数,改用erase函数处理,这样在删除中间的字符字串时,后面的字符会自动向前补齐。
		two = flag.find("1");

		num = flag.substr(two, 11);//复制电话号码

		flag.erase(two, 11);//从电话号码出现的位置two开始,往后删除11位(删除电话号码)

		addr[j].number = num;

		two = 0;

    单元测试样例
    输入:张三,福建省11319936209泉州市
    输出:张三,福建省泉州市

七.psp表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 30
Estimate · 估计这个任务需要多少时间 30 30
Development 开发 120 120
Analysis · 需求分析 (包括学习新技术) 300 420
Design Spec · 生成设计文档 90 60
Design Review · 设计复审 30 30
Coding Standard · 代码规范 (为目前的开发制定合适的规范) 60 30
Design · 具体设计 120 60
Coding · 具体编码 300 500
Code Review · 代码复审 60 200
Test · 测试(自我测试,修改代码,提交修改) 120 0
Reporting 报告 60 60
Test Repor · 测试报告 30 0
Size Measurement · 计算工作量 30 60
Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 120 180
· 合计 1500 1780

八.结合在构建之法中学习到的相关内容与个人项目的实践经历,撰写解决项目的心路历程与收获。

心路历程

    在这次做作业的过程中,发现发现自己的知识储备真的很匮乏,因为自己之前没有主动接触Java和python,所以在这一次做作业的过程中很吃力。在一开始使用c++解题遇到困难的时候,我是选择了学习Java,用Java解题。但是在花费了三天的时间却一无所获的时候,我最后还是选择了放弃Java,使用c++解题。说实话,这次做题目的过程很吃力很难受,也很崩溃。尤其是我在花了ddl前几天转向使用Java却一无所获的时候我十分崩溃。在使用c++的时候,我一直选用字符串操作,虽然后面也得知了,使用转码更适合解决这个问题,但是我在转码问题上花了一天的时间还是没办法吃透,为了避免最后连一小段代码都写不出来的情况,我放弃了编码,继续选择使用字符串操作。但是一直到最后,我也没能写出完整代码,可以说十分崩溃。

收获

    经过这次作业,我对Java有了一些基础的了解,为之后的深入学习相关知识算是开了个头。在这次作业中,我接触到了很多之前没接触过的东西,对于正则也算是有了相对全面的了解(虽然最后我没用上),多多少少都有了一些收获。除此之外,这次最重要的是让我明白了,我在专业方面有很大的缺陷,在这之后,不能像之前一样得过且过了,应该花更多的时间在学习专业知识上。还有一点是,应该尽早开始构思解决办法,这次开始的时间不算晚,但是一直都没深入去思考,到真正操作的时候问题接踵而来,到处都是bug,所以以后还是要尽早开始做题。
posted @ 2019-09-17 22:59  一只胖柠檬  阅读(261)  评论(4编辑  收藏  举报