软工实践第二次作业
GitHub
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 25 | 35 |
• Estimate | • 估计这个任务需要多少时间 | 1015 | 980 |
Development | 开发 | 300 | 320 |
• Analysis | • 需求分析 (包括学习新技术) | 180 | 200 |
• Design Spec | • 生成设计文档 | 10 | 10 |
• Design Review | • 设计复审 | 20 | 10 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 10 |
• Design | • 具体设计 | 20 | 20 |
• Coding | • 具体编码 | 200 | 180 |
• Code Review | • 代码复审 | 30 | 15 |
• Test | • 测试(自我测试,修改代码,提交修改) | 120 | 100 |
Reporting | 报告 | 45 | 25 |
• Test Repor | • 测试报告 | 10 | 10 |
• Size Measurement | • 计算工作量 | 20 | 25 |
• Postmortem & Process Improvement Plan 11 | • 事后总结, 并提出过程改进计划 | 15 | 20 |
合计 | 1015 | 980 |
解题思路
-
因为对java不是很了解,所以我选择用“C++”来解决这个作业。因此在拿到作业后,我先去查找了有关“C++”如何读取和输出文件,以及一些相关的头文件。
-
题目要求的是统计文件内容的字符数、内容的有效行数、以及单词出现频率和匹配的单词个数。
-
输出格式为:
characters: number words: number lines: number <word1>: number <word2>: number ...
在进行统计文件内容字符数时,我想要逐个字符读入这样子方便统计,而在进行统计文件有效行数时,则希望能够按行读取文件,再判断该行是否为有效行数。而在词频统计和统计单词个数上遇到了点问题,感觉这个题很难啊T T,一开始还是没什么思路。后来通过不断查阅资料,以及和同学之间进行交流,尝试使用正则式,通过正则式来筛选题目要求的单词。
设计实现过程
-
首先明确,将要执行的任务分成三个部分:一个负责统计文件的有效字符个数,一个负责统计文件的有效行数,一个负责词频统计和统计单词个数,最后将结果一起输出文本。
-
在写函数前首先是要学习如何读取文件。
-
在查找了相关的资料后,加入了头文件
,在统计字符个数的时候采用逐个字符读入的方法(包括空格和回车):infile >> noskipws; -
在统计有效行数的时候,读取文件使用了get()函数,采取按行读入,并且循环查找行中是否存在除了空格、换行、回车外的字符,如果存在就跳出循环并且行数+1.
-
接下来就是匹配查找符合条件的单词,并且统计单词出现的频率。在词频平统计中套用了正则式的模板,逐个查找,并且实现将大写字母转换成小写字母的功能。最后使用了map去统计出现频率最高的十个单词。
代码说明和测试
-
统计文件内有效字符的个数
int charcount(string filename)
{int count1 = 0;
ifstream infile;
infile.open(filename.data()); //将文件流对象与文件连接起来
assert(infile.is_open()); //若失败,则输出错误消息,并终止程序运行char c;
infile >> noskipws;//逐个字符读入(包括空格和回车)
while (infile >> c)
{if (c >= 0 && c <= 255)
{
count1++;
}
}infile.close();//关闭文件输入流
return count1;
} -
统计单词的个数以及词频统计同时写入文件
bool findword(pair<string, int> elem1, pair<string, int> elem2)
{
return elem1.second > elem2.second;
}
void frequency(string filename)
{
ofstream output("1.txt", ios::app);//调用ofstream函数创建输出文件:1.txt; ios::app让后来写的内容接在上一次写的结尾string s;
map<string, int> find;
regex WordPatternreg("[1]{4}[a-z0-9]");//我们要匹配的单词的正则式
ifstream ifs(filename);//强制读取文件内容
while (ifs >> s)
{
int l = s.length();//
for (int i = 0; i < l; i++)
{
if (s[i] >= 65 && s[i] <= 90)
{
s[i] = s[i] + 32;
}
}//将大写转换成小写
const std::sregex_token_iterator end;
for (sregex_token_iterator wordIter(s.begin(), s.end(), WordPatternreg); wordIter != end; wordIter++)
{//在一行文本中逐个找出单词
//cout<<wordIter<<endl;//每个单词
find[*wordIter]++;//单词计数
}
}
ifs.clear();
ifs.seekg(0);vector<pair<string, int>> ci;
for (map<string, int>::iterator iter = find.begin(); iter != find.end(); iter++)
{
ci.push_back(pair<string, int>(iter->first, iter->second));
}
sort(ci.begin(), ci.end(), findword);
int size = 10;int count3 = ci.size();//统计数组里单词的个数
if (output.is_open())
{output << "word:" << count3 << endl;
if (ci.size() < 10)
{
size = ci.size();
}vector<pair<string, int>>::iterator vit;
for (vit = ci.begin(); vit != ci.begin() + size; vit++)
{
output << "<" << vit->first << ">:" << " " << vit->second << endl;
}
}
output.close();
}
部分测试结果
心得体会
这是第二次实践作业了。说实话,我觉得第二次的实践作业对我来说真的是太难了T T。但是人只有在挫折中才会慢慢成长起来。通过这次实验其实学了很多。以前都知识简简单单敲那种给一个问题写一个程序的代码。而这次除了要编写代码之外,还得学会如何用C++读取和输出文件,如何将代码进行接口封装,当然最重要的是要学习如何百度获取自己所需要的知识。百度真的是万能啊...感慨一下...以前真的很少使用百度学习一些其实课上学不到的东西。比如这次用到的头文件,基本上是上课没有怎么提到过的。真的学会百度非常重要,第一次体会到能够从网上学知识并且能够马上应用到实际。同时真的深切感受到自己的知识点真是太少了,,说实话这次的实践真的是做得挺吃力得...因为vs有点问题...代码之后还会继续修改...说实话这次的实践真的是做得挺吃力得...艰难地成长...
a-z ↩︎