软工1816 · 作业(二)

Github项目地址

Github

PSP表格

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

解题思路

首先,拿到题目的时候,先分析了一下需求:

第一步、实现基本功能

  1. 以命令行参数传入
  2. 统计文件的字符数
  3. 统计文件的单词总数
  4. 统计文件的有效行数
  5. 统计文件中各单词的出现次数,最终只输出频率最高的10个
  6. 按照字典序输出到文件result.txt

第二步、接口封装
把基本功能里的:

  1. 统计字符数
  2. 统计单词数
  3. 统计最多的10个单词及其词频

这三个功能独立出来,成为一个独立的模块,可以在几个地方使用:

  1. 命令行测试程序使用
  2. 在单元测试框架下使用
  3. 与数据可视化部分结合使用

根据题目要求,很容易想到要使用C++文件的读入读写操作来完成此次任务。所以先复习了一下文件的操作,还有上网查了一下词频的统计方法。

设计实现

根据基本功能,划分以下六个函数:

  • isChinese 判断是否是汉字
  • isWord 判断是否是单词
  • isSign 判断是否是分隔符
  • CountChar 统计字符个数
  • CountLine 统计有效行数
  • CountWord 统计单词个数
  • CountTime 统计单词频率

其中统计字符个数和有效行数都是直接读入文件,读一个字符或一个换行符计数变量就加一。比较需要花功夫的是统计单词的个数和单词频率,首先预处理txt里的内容,把所有分隔符替换成空格,并且大写全部转换为小写。之后将string转换为stringstreamstringstream是以空格为界,先读入每两个空格之间的字符串再做汉字和单词的判断。至于单词的排序,采用了mapvector数据结构相结合,先用map保存单词和单词频率的关系,再用vector进行词频和字典序的排序。

代码说明

while (getline(infile, s))
{
	for (int i = 0; i < s.size(); i++)
	{
		if (isChinese(s[i], s[i + 1]) == 1)//是汉字则跳过
		{
			i++;
		}
		else
		{
			if (isSign(s[i]) == 1)//是分隔符
			{
				s[i] = ' '; //将分隔符都换成空格
			}
		}
	}
	str.append(s);
	str.append(1, ' ');
}
transform(str.begin(), str.end(), str.begin(), ::tolower); //将大写转化为小写
stringstream ss(str); //分割成一个个字符串
map<string, int> strMap;  //保存的结果
string strTmp; //分割后的字符串
while (ss >> strTmp)
{
	if (isWord(strTmp) == 1) //判断是否为单词
	{
		map<string, int>::iterator it = strMap.find(strTmp);
		if (it == strMap.end())
		{
			strMap.insert(map<string, int>::value_type(strTmp, 1)); //插入map
		}
		else
			strMap[strTmp]++; //词频+1
	}
}
vector<pair<int, string> > vec;
MapSortOfValue(vec, strMap); //利用vec排序
for (vector<pair<int, string> >::iterator it = vec.begin(); it != vec.end(); it++)
{
	n++;
	if (n <= 10) //选出词频最高的10个单词
	{
		vec2.push_back(make_pair(it->first, it->second));
	}
}
sort(vec.begin(), vec.end(), cmp); //最后再以字典序排序

心路历程

首先很抱歉,由于这一周刚好新生入学,而我作为班导自然义不容辞需要带领他们,新生教育周的活动安排得非常密集,所以我除了上课之外的空闲时间都在带新生。每天基本上都是十一点才能回到宿舍有自己的时间,第二天早上六七点又要起床。很难有时间静下心来写程序。就连作业发表后我也是直到第二天才有时间看一眼。这次作业我没有完成得很好,实现了基本功能后就已经没剩什么时间再完成扩展功能了,还有性能分析和单元测试,这是我之前没有接触过的,再学习新技能明显已经来不及了。单元测试的Bug还没改完,最后在性能分析的时候,VS崩溃了,连运行都运行不了,导致只能先把已做完的部分提交。
所以,建议给自己的deadline可以比任务的实际deadline早那么一天,好应对一些突发状况。
再接再厉吧。下一次作业一定不这么赶了。

posted @ 2018-09-12 21:45  wood崽  阅读(147)  评论(0编辑  收藏  举报