软件工程第一次作业
作业要求的博客链接:https://edu.cnblogs.com/campus/nenu/2016CS/homework/2110
git仓库地址:https://git.coding.net/CTPLY/wf.git
程序要求 : 一个用于统计文本文件(文件名后缀为txt)中的单词出现次数的控制台程序
PSP阶段:
PSP阶段 | 所花时间百分比(607 / min) | 预计所花时间(440/min) |
计划 | 40 | 45 |
·明确需求和其他相关因素,估计每段时间成本 | 40 | 45 |
开发 | 625 | 610 |
·需求分析 | 30 | 35 |
·生成设计文档 | 20 | 25 |
·设计复审(和同学审核设计文档) | 20 | 25 |
·代码规范(为目前的开发制定合适的规范) | 10 | 15 |
·具体设计 | 60 | 55 |
·具体编码 | 320 | 300 |
·代码复审 | 30 | 35 |
·测试(自测、修改代码、提交修改) | 20 | 25 |
报告 | 60 | 40 |
·测试报告 | 5 | 10 |
·事后总结 | 50 | 60 |
项目详情:
首先我拿到这次作业我是有点蒙的,因为不太熟悉字符串和文件的读入,不会就学嘛,在询问同学,观看同学的代码,上网查找资料的种种通道下才艰难的完成这第一次作业。
我看到同学们的代码有用Python,C语言,C++,JAVA的,大家都说用Python简单,但毕竟我学得不精,所以还是选择了自己最熟悉的C语言和C++。
首先遇到的第一个难题是,如何读入文件,这个问题也好解决,网上的知识让我顺利的解决了。我也把代码给贴出来,方便我以后的复习(已标注出处):
int main() { char *path = "E:\\exemple"; //指定文件目录 vector<string> filesName; ofstream file_out("filename.txt"); //打开文本文件 GetFileName(path, filesName); //获取文件名 for(size_t i = 0 ; i<filesName.size(); i ++) //将文件名写入到文本中 { file_out<<filesName[i].c_str()<<endl; } file_out.close(); //关闭文本文件 return 0; } void GetFileName(string path, vector<string>& filesName) { long hFile = 0; //文件句柄 struct _finddata_t fileinfo; //定义文件信息结构体 string p; if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != -1) //使用函数_findfirst()打开文件并获取第一个文件名 { do { if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0) //"."表示当前目录,".."表示父目录 filesName.push_back(fileinfo.name); }while(_findnext(hFile, &fileinfo) == 0); //使用函数_findnext()继续获取其他文件名 _findclose(hFile); //使用函数_findclose()关闭文件夹 } } --------------------- 本文来自 小路孩 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/lsq2902101015/article/details/46551311?utm_source=copy
然后就是计算单词频率的算法部分了,这一部分分析起来也简单,就是把遇到的单词存起来,然后计算出现的次数,在一开始我就简单的使用了一个结构体,里面包含了两个变量,一个是记录单词的first
一个是记录出现次数的second,
/* struct Test { string first; int second; }; */
但去到后面的时候发现,我还要用多一个循环来寻找是否出现过该单词,导致代码量巨大,且不好实现。然后上网查了一下发现有两个STL能使用,一个是vector,一个是map。
我首先使用了vector,同样是存两个变量,m1,m2。
/*
void MyPushback(std::vector<Test> & vecTest, const int &m1, const int &m2) { Test test; test.member1 = m1; test.member2 = m2; vecTest.push_back(test); } */
但最后同学跟我说了个更好的办法,使用了map<string,int> wcount, ++wcount[w],w表示出现的单词,wcont[w]直接记录次数,这个操作打开了我新世界的大门,之前什么循环找是否出现过字符的操作是什么鬼东西,太垃圾了。
void Cwords(){ map<string,int> wcount; bool flag = gnumber(); bool tmp = false; string w; string s; for (int i = 0;i < str.length();i++){ while(str[i] >= '0' && str[i] <= '9' || str[i] >= 'a' && str[i] <= 'z'){ tmp = true; s += str[i]; i++; } if(tmp){ w = s; if(w[0] > '9' || w[0] < '0'){ //vector<int>::iterator result = find( L.begin( ), L.end( ), 3 ); ++wcount[w]; } s = ""; w = ""; tmp = false; } } }
样例测试
功能1:
功能2:
功能3:
从控制台读入英文单篇作品测试:
总结反思:
这次的作业查了相当多的资料,跟同学交流了好久,现在真的觉得自己的代码水平差好远,对于字符串的处理,还有如何读入文件名之之类的,在这次作业中都得到了充分的提高,还有排序啥的,都得继续加强。争取下一次作业能更早,更好的完成。