第一次个人编程作业

从自学到自闭

一.github仓库(Updating)

二.PSP

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

三.解题过程

  • 工具选择:c++

  • 解题思路

    • 将类型1和类型2的地址,转换成字符串匹配和切割问题,分开解析,解析函数分别包装在两个类中(Five_add_analysis五级地址分析类和Seven_add_analysis七级地址分析类)

    • 对于类型3的地址,不调api的话貌似需要很大的数据量,能力有限,时间也很仓促,暂时放弃。恳请评测的同学手下留情

  • 实现方法(针对类型1和类型2,主要通过string库和regex库的函数实现)

类: Five_add_anaysis 函数接口功能
void provs_seperate() 一级解析(省/直辖市)
void cities_seperate() 二级解析(市/直辖市)
void counties_seperate() 三级解析(区/县/县级市)
void towns_seperate() 四级解析(街道/镇/乡)
void detail_seperate() 五级解析(详细地址)
void info_collect() 地址解析调用接口函数

class Seven_add_anaysis:public Five_add_anaysis,并重写一级解析,增加五,六级解析

继承类:Seven_add_anaysis 函数接口功能
void provs_seperate() 一级解析(省/直辖市)
void road_seperate() 五级解析(路/街道/街)
void gate_number() 六级解析(门牌号)
void detail_seperate() 七级解析(详细地址)
void info_collect() 地址解析调用接口函数
  • 解析省市的数据用了打表法,将省份、省份对应的下一级城市打成表,以减小查找城市的工作量(详见代码)

    主要函数(五级地址的一级解析)

void provs_seperate()//解析省
	{
		//prov_tag作为二级解析城市对应省份下标
		int flag;
		for (int i = 0; i < 23; i++)
		{
			/*地址中带"省"*/
			string temp = provs[i].substr(0, provs[i].size() - 2); //提取省份名称,例如:福建
			if ((flag = addr.find(provs[i])) != -1)
			{
				pro = provs[i];
				prov_tag = i;
				addr.erase(flag, provs[i].size()); //擦去“省”
				return;
			}
			/*地址中不带"省"的省*/
			else if ((flag = addr.find(temp)) != -1)
			{
				pro = provs[i];
				prov_tag = i;
				addr.erase(flag, temp.size()); //擦去“省”
				return;
			}

			/*直辖市、自治区前四个*/
			if (i < 4)
			{
				/*直辖市*/
				if ((flag = addr.find(direct_city[i])) != -1)
				{
					pro = direct_city[i];
					addr.erase(flag, direct_city[i].size());
					prov_tag = i + 23;//区分直辖市
					return;
				}
				temp = direct_city[i].substr(0, direct_city[i].size() - 2);//提取直辖市名称,例如:北京
				if ((flag = addr.find(temp)) != -1)
				{
					pro = direct_city[i];
					addr.erase(flag, temp.size());
					prov_tag = i + 23;//区分直辖市
					return;
				}

				/*自治区*/
				if ((flag = addr.find(zzq[i])) != -1)
				{
					pro = zzq[i];
					addr.erase(flag, zzq[i].size());
					prov_tag = i + 27;//区分自治区
					return;
				}
				temp = zzq[i].substr(0, zzq[i].size() - 6);//提取自治区名字如内蒙古
				if ((flag = addr.find(temp)) != -1)
				{
					pro = zzq[i];
					addr.erase(flag, temp.size());
					prov_tag = i + 27;//区分直辖市
					return;
				}
			}
			/*自治区*/
			if (i == 4)
			{
				if ((flag = addr.find(zzq[i])) != -1)
				{
					pro = zzq[i];
					addr.erase(flag, zzq[i].size());
					prov_tag = i + 27;//区分自治区
					return;
				}
				temp = zzq[i].substr(0, zzq[i].size() - 6);//提取自治区名字西藏
				if ((flag = addr.find(temp)) != -1)
				{
					pro = zzq[i];
					addr.erase(flag, temp.size());
					prov_tag = i + 27;//区分直辖市
					return;
				}
			}
		}
	}

四.性能分析&&单元测试

输入数据:

输出结果:

主耗函数:


由性能分析图可知,消耗最大的函数是七级地址解析towns_seperate(),详细分析后发现原因是正则表达式的函数匹配所需时间较长,耗费较大。

至于单元测试这块,实话实说,看了好多资料,大概懂得测试步骤,但是具体如何编写测试单元还在学习中代码覆盖率就做不了了。没法做单元测试只能手动调试了,自己拿了几个数据测了一下,基本上每个函数都调用过,结果还是比较符合预期的,之后会做完单元测试会持续更新放过孩子叭

五.异常模块处理

主要是对类型3的输入进行捕捉并过滤,目的是为了配合代码的功能,具体实现:

try
{
    type = type_seperate();
    bool  flag;
    if(type == "1!"||type == "2!")flag = True;
    else flag = False;
}catch(bool  d){
    out<<"Type wrong!"<<endl;
}

六.心路历程

  • 我人傻了 一开始看完题目毫不迟疑地选择了c++,没想到竟然上了一条自闭路,想起当初的鲁莽,现在就是非常后悔c++写的我脑阔疼

  • 我太难了 第一次作业就做这么“有趣”,做的过程中麻烦很多,有很多不会的东西得边学边用,效率极低,我裂开来。唉,果然知识这东西还是得靠积累啊,速成简直是痴人说梦!

  • 我真的好难 代码构思了一天,花了两天进行初步实现,之后又花了一天的时间对代码进行分析改进debug到心态炸裂,怎么使用评测工具又瞎琢磨了一天到现在还搞得不太明白,凌晨四点半的福大也是差点就见到了无奈顶不住,实在肝不动了。肝了几天身心俱疲,希望结果不会太惨!弱弱地再次恳求评测的大佬高抬贵手,求求了

一句话总结:第一次编程作业,从自学到自闭,毫无体验。。。

原文地址:https://www.cnblogs.com/lxccccc/p/11518432.html