个人第4次作业----原型设计
课程属性
git地址 | https://github.com/sulei1999/WordCount.git |
---|---|
结对伙伴作业地址 | https://www.cnblogs.com/sl1999/p/11667779.html |
一、结对两人信息
姓名 | 学号 |
---|---|
汤善康 | 201831022208 |
粟磊 | 201831031328 |
part.1----个人开发流程(PSP)
###
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 50 | 60 |
Estimate | 估计这个任务需要多少时间 | 40 | 30 |
Development | 开发 | 200 | 400 |
Analysis | 需求分析(包括学习新技术) | 100 | 100 |
Design Spec | 生成设计文档 | 100 | 90 |
Design Review | 设计复审(和同事审核设计文档) | 100 | 80 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 30 | 60 |
Design | 具体设计 | 300 | 400 |
Coding | 具体编码 | 1000 | 1200 |
Code Review | 代码复审 | 400 | 600 |
Test | 测试(自我测试,修改代码,提交修改) | 400 | 300 |
Reporting | 报告 | 200 | 120 |
Test Report | 测试报告 | 60 | 50 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortem & Process Improvement plan | 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 3070 | 3600 |
part.2----前期分析
###
1.解题思路描述
(1) 拿到题目,大略统观之后,首先注意到三个点:①命令行窗口运行程序②主函数main设置参数③命令行输入文件名参数进行读取,前面两部分要在网上进行学习搜索,最后一个不得不提前学习c++课本上后面的输入输出流部分内容。最后虽然由于一些原因采用了VS2017内部打开程序,但在这个过程中学到了那种方法(因为前期几天都是采用的命令行传参,最后在修改代码中出了问题,以及其他因素才临时改成正常窗口输入文件名)
(2)然后就是想到建立一个类,其内包含字符、单词、行等的记录变量,以及相关函数
2.设计实现过程
如上所言,需要用到一个类“Wordcount”,设置私有成员“characters”(统计记录字符数)“words”(统计记录单词数)“line”(统计记录行数),因此又要有三个公有成员函数用于返回三个私有成员值getcharacters()、getwords()、getlines(),然后再有三个对应的计算函数等等。
大体框架如下:
part.3----代码实现
###
1.代码规范制定
这方面并没有那么严格死板地有所制定,而是彼此都约定俗成地做到了规范书写代码,并给出适当注释说明
2.代码互审
这个步骤我认为是非常必要的,此次任务完成过程中更是深有体会,很多错误自己多次检查都发现不到,结对伙伴却容易轻松发现,可以极大提高编程效率,例如我所负责的函数“ merge”部分出现了一个问题始终没有找到解决方法,多亏了伙伴粟磊得以实现成功运行
3.性能分析
Image
4.代码说明
结构体
class Wordcount
{
public:
Wordcount countcha(char *, Wordcount);
Wordcount countword(char *, Wordcount);
Wordcount countline(char *, Wordcount);
int getcharacters();
int getlines();
int getwords();
char *content;//存放文本文件数据
void init();//构造函数的功能,将数据初始化
private:
int characters;
int words;
int lines;
};
计算字符数单词数和行数
Wordcount Wordcount::countcha(char *t, Wordcount f1)
{
int i = 0;
ifstream myfile;
myfile.open(t);
if (!myfile.is_open())
{
cout << "文件打开失败" << endl;
}
char c;
myfile >> noskipws;//强制读入空格和换行符
while (!myfile.eof())
{
myfile >> c;
if (myfile.eof())///////////////////////////////////////////////
break;//防止最后一个字符输出两次
i++;
}
f1.characters = i;
myfile.close();
return f1;
}
Wordcount Wordcount::countline(char *t, Wordcount f1)
{
ifstream myfile;
myfile.open(t, ios::in);////////////////////////////////////
int i = 0;
string temp;//作为getline参数使用
if (!myfile.is_open())
{
cout << "文件打开失败" << endl;
}
while (getline(myfile, temp))
{
if (temp.empty())////////////////////////////////////////////////
continue;
i++;
}
f1.lines = i;
myfile.close();
return f1;
}
返回私有元素值
int Wordcount::getcharacters()
{
return characters;
}
int Wordcount::getlines()
{
return lines;
}
int Wordcount::getwords()
{
return words;
}
主函数
int main(/*int argc, char *argv[]*/)
{
clock_t start = clock();
int i, num = 0, j, r = 0;
Wordcount f1;
char a[200];///////////////////////////
f1.init();
scanf_s("%[^\n]", a, 200);
/* for (int i = 0; a[i] != NULL; i++)
{
if (a[i] == '-')
if (a[i + 1] == 'i')
for (int j = i + 3; a[j] != ' '; j++)
{
wr[r] = a[j];
r++;
}
}*/
for (int i = 0; a[i] != NULL; i++)
{
if (a[i] == '-')
if (a[i + 1] == 'i')
for (int j = i + 1; a[j] != NULL; j++)
{
if (a[j] == ' ')
if (a[j + 1] != ' '&&a[j + 1] != '-') //输出文件入口判断
{
wr = a + j + 1;
break;
}
}
}
cout << wr << endl;
/* for (int i = 0; a[i] != NULL; i++)
{
if (a[i] == '-')
if (a[i + 1] == 'o')
for (int j = i + 1; a[j] != NULL; j++)
{
if (a[j] == ' ')
if (a[j + 1] != ' '&&a[j + 1] != '-') //输出文件入口判断
{
wo = a + j + 1;
break;
}
}
}*/
for (int i = 0; a[i] != NULL; i++)
{
if (a[i] == '-')
if (a[i + 1] == 'o')
for (int j = i + 3, k = 0; (a[j] != ' '); j++, k++)
{
wo[k] = a[j];
}
}
if (!wr)
{
cout << "未输入文件名或文件不存在" << endl;
return 0;
}
f1 = f1.countcha(wr, f1);
f1 = f1.countline(wr, f1);
f1 = f1.countword(wr, f1);
sWord *ww = new sWord[f1.getwords()];//给结构体分配一个大小为单词数目的动态空间
sWord *temp = new sWord[f1.getwords()];
map<string, int>::iterator it;
it = mapword1.begin();
for (it; it != mapword1.end(); it++)
{
ww[num].w = it->first;
ww[num].count = it->second;
num++;
}
sort(ww, temp, 0, num - 1);//把已经按字典序排号按出现频率进行从大到小的归并排序
//输出
ofstream fout;
fout.open(wo);
if (!fout)
cout << "文件打开失败" << endl;
// cout << "characters: " << f1.getcharacters() << endl;
fout << "characters: " << f1.getcharacters() << endl;
// cout << "words: " << f1.getwords() << endl;
fout << "words: " << f1.getwords() << endl;
// cout << "lines: " << f1.getlines() << endl;
fout << "lines: " << f1.getlines() << endl;
if (num < 10)
{
for (i = 0; i < num; i++)
{
// cout << "<" << ww[i].w << ">" << ": " << ww[i].count << endl;
fout << "<" << ww[i].w << ">" << ": " << ww[i].count << endl;
}
}
else
{
for (i = 0; i < 10; i++)
{
// cout << "<" << ww[i].w << ">" << ": " << ww[i].count << endl;
fout << "<" << ww[i].w << ">" << ": " << ww[i].count << endl;
}
}
fout.close();
delete[]temp;
delete[]ww;
free(f1.content);//动态空间释放
clock_t ends = clock();
cout << "运行时间 : " << (double)(ends - start) / CLOCKS_PER_SEC << "秒" << endl;
return 0;
}
按字典次序排序
void merge(sWord *a, sWord *c, int l, int mid, int r) {
int i = l, j = mid + 1, m = 1;
while (i <= mid && j <= r) {
if (a[i].count < a[j].count) c[m++] = a[j++];
else c[m++] = a[i++];
}
while (i <= mid) c[m++] = a[i++];
while (j <= r) c[m++] = a[j++];
for (int k = 1; k <= r - l + 1; k++)
a[l + k - 1] = c[k];
}
void sort(sWord *a, sWord *c, int l, int r) {
if (l < r) {
int mid = (l + r) / 2;
sort(a, c, l, mid);
sort(a, c, mid + 1, r);
merge(a, c, l, mid, r);
}
}
Image运行截图
以“-o 要读取的文档1路径 -i 要写入的文档2路径”输入,即可将对文档1的读取结果写入文档2中
part.4----项目收获与心得
###
个人总体感受
由于首次本来要求中要使用命令行运行C++程序(最终和伙伴讨论后一致决定放弃这种参数输入方法),而且C++学习进程的严重滞后,这里又要用到后面的输入输出流,心头不禁一颤,这也是为什么“具体编码”预估时间高达十六小时,以及最终仍然无奈延期,很多具体编码部分都要双手敲击着键盘,大腿上还放着C++课本,电脑屏幕上后台放着数不清的浏览器窗口(CSDN等网站的各种技术博客),然后很多次还都写了半天代码,出现错误多番查找修改不过来只好一切清零,换条路从头再来
而这学期本就课多,拿我来说,一学期有30+学分的课程,整个学校比我课多的寥寥无几,天天除了周四下午有空,一周五天,天天满课,全是作业,课下能给这门课的时间本就有限... ..感觉是大学以来完成作业最困难的一次
结对心得与收获
可以说能坚持写下来,主要靠的两个人互相鼓励吧,自己的话不知道要放弃过多少次了,而且自己的话,一周自学所需要的全部内容... ...无疑是不可能事件,靠着两人发挥各自擅长的方面,以及同时不停地“百度”,总算在最后时间完成了作业,可以说,这次我对“1+1>2”的体会是非常深刻的,感谢我的伙伴,粟磊。