zoukankan      html  css  js  c++  java
  • 第一次个人编程作业

    第一次个人编程作业

    Part 1 : Github项目地址

    由于我的vs一直没办法直接把项目上传到github上,一直推送失败。所以我只能在github的对应仓库上“create new file",直接把代码贴上去,望谅解。通过设置新的分支后已经可以成功推送!耶!


    Part 2 : PSP(Personal Software Process)表格

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

    Part 3 : 解题思路描述

    (1)拿到题目后如何思考?

    在看到助教姐姐发布的第一次编程作业后,我的内心是崩溃的。由于在给出的三种语言要求中,java没接触过,python选修课学过但学得很浅,所以我就选择了用c++来解题。后来发现用c++简直太难了啊啊啊啊!停止土拨鼠尖叫,回到题目,题目要求将小王打乱的地址簿规范化处理。对我来说,难点在于:一是地址中的“省”、“市”等关键字有可能残缺,这就说明没办法简单的通过匹配该关键字来提取。只能通过暴力打表或者引入地图API来匹配处理;二是没处理过文件的输入输出,需要进一步了解这里面有没有什么陷阱(坑)以及如何规范输入输出;三是好多处理问题上的细节,类处理函数处理之类的。总之就是一个字,。但生活还是得继续下去,冲!

    (2)如何查找资料?

    主要有四种方式:翻阅以前的c++教材和c++ primary,熟悉一下可能会用到的语法;利用搜索引擎查找地址模糊匹配等与题目相关类似的博客资料;询问身边的大佬们,向他们请教思路;围观软工群里“神仙打架”,我还没想好怎么做他们已经写好评测工具等着了QUQ。


    Part 4 : 设计实现过程

    (1)代码组织方式

    我定义了一个person类,里面包含成员变量total,name,telnum,province,city,county,street,detailaddr,函数则有stringtowstring转换函数、wstringtostring转换函数、省提取函数、市提取函数以及以下几级地址的提取函数,通过提取函数将提取出来的规范地址赋值给类中对应的成员变量,转换函数则用来实现string和wstring的相互转换。

    全局变量与函数如下图:

    Person类成员变量如下图:

    以下是关系函数的流程图:

    (2)算法的关键

    总的来说:

    我的算法的关键主要是地址的提取函数和字符转换函数。因为不会调用地图API(别问,问就是菜!),所以只能采用暴力的本方法来查找匹配。我建立了地址数组,将普通地址和特殊地址分开,比如直辖市和自治区单独建组,不与普通省份一起,方便匹配并且提取规范地址,赋值比较方便,通过返回已提取地址的字数来简化地址,以便下一步匹配提取。但这种方法非常暴力,效率比较低,还需要进一步的完善改进。;通过stringtowstring和wstringtostring的转换函数来实现字符的转换,方便对字符串的处理和输出。

    地址提取函数:

    一是省、直辖市、自治区的地址提取函数。因为这种情况下的参数相对较少,因此我就建立了三个全局变量字符数组来存省、直辖市、自治区的地址名称,然后通过函数进行对比匹配。由于存在直辖市和自治区这两种比较复杂的情况,因此我将其分开进行判断,先进行直辖市的判断:

            //判断直辖市
    	for (int i = 0; i < 4; i++) {
    		if (t == direct_pro[i]) {
    			addr[p].province = t; addr[p].city = t; addr[p].city += L"市";
    			if (obj_[2] == L'市') { return 3; }
    			else return 2;
    			break;
    		}
    	}
    
    

    自治区的判断:

    	//判断自治区
    	if (z == autop[2]) { addr[p].province = L"西藏自治区"; return 5; }
    
    	if (z == autop[0]) { addr[p].province = L"内蒙古自治区"; return 6; }
    
    	if (z == autop[1]) { addr[p].province = L"宁夏回族自治区"; return 7; }
    
    	else if (z == autop[3]) { addr[p].province = L"广西壮族自治区"; return 7; }
    
    	if (z == autop[4]) { addr[p].province = L"新疆维吾尔自治区"; return 8; }
    
    

    普通省份的判断,注意需要把黑龙江省单独提出来判断:

    	//判断普通省份
    			for (int j = 0; j < 22; j++) {
    				if (t == provincebook[j]) {
    					t += L"省";
    					if (obj_[2] == L'省') { addr[p].province = t; return 3; break; }
    					else { addr[p].province = t; return 2; break; }
    				}
    			}
    
    

    二是对市、区/县/县级市、街道/镇/乡、详细地址的提取。到这里我就GG了。不会调地图api,而如果采用上述方法,需要存的参数太过于庞大,因此只能先不考虑“市”、“县”等关键字缺失的情况和部分关键字与地名重合的情况,直接通过匹配关键字来提取。显然这是一个漏洞很多的本方法,还需要想出办法来改进。

    	//识别“市”关键字
    	for (int i = 0; i < 5; i++) {
    		city_ += obj[i];
    		if (obj[i] == L'市') {
    			addr[c].city = city_;
    			return i + 1; break;
    		}
                }
    
    

    字符串转换函数:

    从文件直接getline得到的字符串对汉字的处理比较奇怪,一个汉字需要占字符数组的两个单位,这给字符匹配和处理增加了很多麻烦。然后我就去百度惹(百度是镇滴好用!我爱csdn!)~发现通过把string转换成wstring后,再进行各种处理,会方便很多。因此就增加了两个转换函数。
    以下是把string转换成wstring的函数:

    wstring result;
    	//获取缓冲区大小,并申请空间,缓冲区大小按字符计算  
    	int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
    	TCHAR* buffer = new TCHAR[len + 1];
    	//多字节编码转换成宽字节编码  
    	MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
    	buffer[len] = '';             //添加字符串结尾  
    	//删除缓冲区并返回值  
    	result.append(buffer);
    	delete[] buffer;
    	return result;
    }
    
    

    Part 5 : 计算模块接口部分的性能改进。

    (1)记录在改进计算模块性能上所花费的时间,描述你改进的思路。

    要改进计算模块性能,我觉得最重要的还是能学会调用地图API来进行匹配处理(或者还有另一种更简单的方法?),简化编程和节约时间空间。然鹅这个我还不会啊啊啊,给我时间,我觉得我阔以!

    (2)展示一张性能分析图(由VS 2017/JProfiler的性能分析工具自动生成),并展示你程序中消耗最大的函数。

    或许性能分析图是下面这个嘛?问了度娘就只查到了这个,应该是的吧……

    CPU使用情况百分比

    热路径和执行单个工作最多的函数

    调用树(可见程序中消耗最大的函数)


    Part 6 : 计算模块部分单元测试展示。

    暂时还没有做单元测试这一项。待完成后再来补。


    Part 7 : 计算模块部分异常处理说明。在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。

    由于代码本身存在的bug问题,除了较为正常的未缺关键字的地址,异常情况的发生率还挺高的。特别是因为关键字引起的异常,比如:

    1、关键字缺少。

    “张三,福建福州闽13599622362侯县上街镇福州大学10#111.”这种情况下提取结果为{“姓名”:“张三”,“手机”:“13599622362”,“地址”:[“福建省”,“”,“福州闽侯县”,“上街镇”,“福州大学10#111.”]},使得市的提取失败,福州被匹配到县,间接导致县的提取失败。

    2、关键字与地名重复。

    “小美,北京市东15822153326城区交道口东大街1号北京市东城区人民法院.”这种情况下提取结果为{“姓名”:“小美”,“手机”:“15822153326”,“地址”:[“北京”,“北京市”,“东城区”,“交道”,“口东大街1号北京市东城区人民法院.”]},将详细地址错误匹配到上级地址中。


    Part 8 : 个人心得体会

    总归一个字,“菜”!两个字“好菜”!三个字,“我好菜”!哎,果然编程能力都是要靠时间日积月累,临时抱佛脚真的会很难受。不过这次编程,大概是我大学以来,除了打比赛以外,做得最认真的编程作业了。而且也大部分都是自己”薅光头发“写出来的,虽然功能还很垃圾,用了很多笨方法,但就有一种自己尽力了而且收获得蛮多的“快感”。也许这就是我当初选择计算机专业想追求的那种满足感吧。未来熬夜秃头打代码的日子还长着,需要进步学习的还非常非常多,要坚持!冲!

  • 相关阅读:
    python 杂谈
    python: list转字符串
    dataframe
    time模块
    python 调试器
    BAT机器学习面试1000题系列(41-45题)
    join()函数
    value_counts()
    模型评估
    04flask_scripts使用
  • 原文地址:https://www.cnblogs.com/cyj0107/p/11532946.html
Copyright © 2011-2022 走看看