第一次个人编程作业

Github项目地址

项目地址

PSP表格

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

解题思路

拿到这个题目,能够明显的看出是字符串的提取问题。​由于对python还不是特别熟悉,我决定用C++写。我的思路是把姓名和手机先判断出来,判断出来后删除,再对地址进行分析。
首先通过判断第一个字符确定是五级地址分离还是七级地址分离。我发现姓名之后都有一个”,”,因此可以利用这个逗号把姓名先提取出来,然后消除。我通过百度了解到,手机号码可以利用正则表达式提取。省份的话,除了黑龙江省,其余带“省”字的省份都是两个字,因此把黑龙江特殊处理,我用暴力把省分离,市的话也是类似方法。对于第三级和第四级地址的分离,则是采用正则表达式,那么剩余的则是详细地址。至于七级地址里详细地址的分离,依旧采用正则表达式。最后,就是根据题目的要求输出。

设计实现

代码设计主要包括主程序和诸多功能函数,例如、类型判断函数(leixing)、寻找名字函数(findname)、手机号分离函数(findtel),地址分离函数(separate)等。内部的调用关系大致是,主程序执行,先调用类型判断函数,确定是哪级分离,之后删除X!(表级数)的两个字符;然后依次调用寻找名字、手机号分离的函数,最终的到姓名、手机、地址等三个独立的字符串,紧接着调用地址分离函数对地址进行一级一级的提取。
具体流程下图所示:

关键代码

本次代码中最难最关键的是通过正则表达式达到分离效果

划分内容 代码展示
11位手机号码 regex r("\d{11}");
县/区/县级市级划分 regex r("^.+(县/市/区)");
街道/镇/乡划分 regex q("^.+(街道/镇/乡)");
街/路/巷 regex q("^.+(街/路/巷)");
门牌号 regex q("^.+(号)");

此外,C++文本的读取也写入也让我卡了好久……

内容 代码展示
读取 ifstream input; input.open(argv[1]);
写入 ofstream out; out.open(argv[1]);
头文件加 fstream

关键函数代码展示

string findtel(string a)//寻找手机号
{
	smatch tel;
	regex r("\\d{11}");
	regex_search(a, tel, r);
	string newtel = tel.str();
	return newtel;
}

int sign1,sign2;
	sign1 = loc.find('省');//分离省
	if (sign1 == 5)
	{
		pro = loc.substr(0, sign1+1);
		loc.erase(0, 6);//擦除省
	}
	else if (sign1 == 7)
	{
		pro = loc.substr(0, sign1+1);
		loc.erase(0, 8);//擦除省
	}
	else//地址没有省字
	{
		flag1 = 1;
		sign2 = loc.find('龙');
		if (sign2==3)
		{
			pro = loc.substr(0, 6);
			loc.erase(0, pro.length());
		}
		else
		{
			pro = loc.substr(0, 4);
			loc.erase(0, pro.length());
		}
	}
//县/区/县级市
	regex r("^.+(县|市|区)");
	smatch t;
	regex_search(loc, t, r);
	country = t.str();		
	loc = regex_replace(loc, r, "");
//街道/镇/乡
	regex q("^.+(街道|镇|乡)");
	smatch p;
	regex_search(loc, p, q);
	town = p.str();
	loc = regex_replace(loc, q, "");

运行结果展示

输入数据:

输出数据:

性能分析展示

程序中消耗最大的函数可从百分比中得以体现。

单元测试及覆盖率

我看了构建之法2.1里面相关的内容,但由于代码上的问题比较多(呜呜),且书里是用C#写的。这块没有理解清楚,所以没有做。这次作业之后会好好研究尝试的(保证)
看书觉得几个比较印象深刻的点在这先总结下:

  • 创建单元测试的主要步骤:
    • 设置数据
    • 使用被测试类型的功能
    • 比较实际结果和预期结%果
  • 100%的代码覆盖率并不等于100%的正确性

异常分析

我的异常主要在于输出会出现乱码和文件读取。(心态爆炸
输出乱码展示:

  • 省字的输出一直会出现乱码。后来换了一种输出方式。可能是没有转码所以导致省变成适,引号变成问号。
  • 所有函数完成之后,想加入文件的读取,运行时一直出错,原因可能是头文件忘写以及文本地址复制后,“"要改成”//“。
  • 三级难度的样例无法通过。(有点难,暂时没有处理

心路历程与收获

  • 能力低下,菜到安详……拿到题目力不从心,要求好多啊……造成这种感觉的原因主要有两个方面:第一方面:对github,vs等工具使用的不熟悉,学习新知识例如单元测试等的效率太低;第二方面,编程能力低。
  • 从一些采用java和python编写该题的同学了解到,他们的代码量,远小于用C++编写。python虽然暑假有自学,但是感觉太过皮毛。接下来考虑深度学习python,并争取在下次作业尝试用python编程。
  • 通过这次的编程作业,我重温了C++的string库函数,尝试正则表达式以及C++文件的读取与写入。虽然学习过程艰难、心累,但还是有所收获吧。
posted @ 2019-09-17 22:16  Joyinginging  阅读(177)  评论(4编辑  收藏  举报