第一次个人编程作业

github链接

一、PSP表格

(2.1)在开始实现程序之前,在附录提供PSP表格记录下你估计将在程序的各个模块的开发上耗费的时间。(3')

(2.2)在你实现完程序之后,在附录提供的PSP表格记录下你在程序的各个模块的开发上实际花费的时间。(3')

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

二、计算模块接口

(3.1)计算模块接口的设计与实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。(18')

敏感词类MGC://存储输入的敏感词信息,按词存储
包括:敏感词序号,敏感词本身的字符串,长度(utf-8码的长度,一个汉字占3个字节),敏感词类型(中文|英文),敏感词总数

行类HANG://存储需要检测的文本,按行存储
包括:行序号,行本身的字符串;长度(同上),行总数

答案类ANS://将得到的结果按行存储
包括:敏感词序号,行序号,对应行的字段定位(便于输出问题字段),答案总条数

检测函数search://对敏感词检测,是程序的核心算法,也是难度最高,占用资源最多的部分

void search(MGC &M,HANG &H)//输入对应的敏感词和行,不破坏行和词本身,检测到敏感字段即存入答案类
{
	int i = 0, j = 0, head;
	if (M.k == 1)//敏感词为汉字
	{
		//连续3个字节相同,则进行匹配;若敏感词长度为n字节,则需匹配n/3次才算完成
		for (; j < H.l; j++) if (H.s[j] == M.w[i]&& H.s[j+1] == M.w[i+1]&& H.s[j+2] == M.w[i+2])
		{
			if (i == 0) head = j;//第一次匹配时,对文章对应位置定位
			i += 3;
			j += 2;
			if (i == M.l)//匹配完成,记录信息,从当前位置继续查找该敏感词
			{
				i = 0;
				Ans[Ans_num].mgc_num = M.num;
				Ans[Ans_num].hang_num = H.num;
				Ans[Ans_num].h = head;
				Ans[Ans_num++].e = j;
			}
		}
	}
	else//敏感词为英文
	{
		//不区分大小写,相同则匹配;若敏感单词长度为m字节,则匹配m次
		for (; j < H.l; j++) if ((H.s[j] == M.w[i]) || (H.s[j] - M.w[i] == 32 && M.w[i] <= 'Z') || (M.w[i] - H.s[j] == 32 && M.w[i] >= 'a'))
		{
			if (i == 0) head = j;
			i++;
			if (i == M.l)//匹配完成,记录信息,从当前位置继续查找该敏感词
			{
				i = 0;
				Ans[Ans_num].mgc_num = M.num;
				Ans[Ans_num].hang_num = H.num;
				Ans[Ans_num].h = head;
				Ans[Ans_num++].e = j;
			}
		}
	}
}

输出函数ANS_print: //输出优先级:将答案类ANS输出到指定路径,行序号优先;同行时按敏感词序号优先;对于行号和词号一致的语句,看两者在对应行的出现顺序

思路:
分别读入敏感词文件f1、待检测文本f2,存储到对应的类中;
检测函数search:我的做法是将字符串的ASCII码与敏感词的ASCII码进行匹配(虽然能很快查找到正常情况下的敏感字段,但对同音字和拆边旁的情况存在很大的困难)能找到多少找多少,存入对应的类中
最后由对应的函数将结果输出

流程图:

(3.2)计算模块接口部分的性能改进。记录在改进计算模块性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2019、JProfiler或者Jetbrains系列IDE自带的Profiler的性能分析工具自动生成),并展示你程序中消耗最大的函数。(12')



以上是用范例测试后得到的结果,其中检测函数search占了40%以上的cpu时间,占比最大;另外输入数据的处理也要花费不少的cpu时间;

结果与预想差不多,毕竟整个程序的核心算法就是敏感词的检测函数search,并且按我的算法,search的时间复杂度与(敏感词数*文本行数)成正比,当样例的敏感词数增加时,search消耗的cpu占比或许再度增加;

虽然占比较高,但实质消耗的时间相对合理,也没有改进的思路,故没对其进行改进;

(3.3)计算模块部分单元测试展示。展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。(12')

测试1:(即作业给出的范例)

输入对应的3个地址:

我输出的答案:

示例给出的答案:

(我只找出了400个,主要是目前的进展对同音字和边旁还不能很好的解决)

测试2:分别给出(敏感词a,文章b, 答案c)


测试3:分别给出(敏感词a,文章b, 答案c)


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

//读入敏感词文件f1,并放入敏感词类的数组(Mgc[])中
	cin >> dz;
	ifstream f1(dz);
	if (!f1) cout << "open error!" << endl;
        。。。。。

当读入文件出现问题时,输出

open error!

例如:

当输入正确的路径时,不会报错:

三、心得

(4.1)在完成本次作业过程的心得体会(3')

开发思路及遇到的困难:
1.用c++读写文件时遇到困难,学习了fstream等知识,掌握基本的读写文件流;

2.用DevC++和VS测试txt文件的读写功能时,发现中文的乱码现象;经学习和查阅资料,问题在于txt文件默认用utf-8编码,而Windows控制台默认用ANSI(GBK)编码,故控制台会出现中文的乱码,虽不影响该次作业生成的txt文件结果,但给开发、测试及维护过程造成了许多的不方便;

解决方法:将VS设置成utf-8编码,并且在main函数开始处加入语句:system("chcp 65001"),语句功能为将控制台修改为utf-8编码;使程序全程使用utf-8编码,便于编写和维护;

3.对程序进行测试,测试过程中遇到输入的路径打不开的现象,发现路径中包含了中文,改为英文后此问题便没再发生

总结:学了许多知识,但离完全攻下此题还有很大的差距,还要再努力呀

原文地址:https://www.cnblogs.com/miaohengming/p/15233266.html