2021软件工程-第二周作业
这个作业属于哪个课程 | 软件工程-计算机科学与技术一班 |
---|---|
这个作业要求在哪里 | 202103226-1 编程作业 |
这个作业的目标 | 理解软件工程在实际项目开发当中的使用 |
其他参考文献 | 《码出高效_阿里巴巴Java开发手册》/《腾讯c++代码规范》/《Python PEP8》 |
1.0 Github项目地址
2.0 代码规范制定链接
3.0 解题思路描述 & 设计与实现过程
其实这个题目在本质上就是对于字符串的切割与统计,简单的字符串操作。但是如何将简单的东西做出不一样的效果,这就是我所头疼的事情,在经过了深思熟虑之后,我决定大量采用 STL 与 Stream 操作解决题目。
这个题目的第一个难点是 汉字字符的去除。汉字字符在这里可以用另一个名称来代替:非ASCII字符。这样就很好解决问题了。我们只需要将ASCII字符在 0~127 范围的字符保存下来就好。
第二个难点是单词的统计与保存。这里我采用的是 vector
类来进行储存。我首先统计相关单词是否符合语法和内容,在统计出现次数。
第三个难点是词汇频率的统计。这里可以说是整个题目最有意思而且富有难度的地方。我用了我很少用到的一个STL工具,map
类。这个类天然支持键值对,并且通过查阅相关文档我可以得知。其实我们需要使用STL中的一个叫做 pair
的模板类。这个类仅有两个数据成员first 和 second,即 key 和 value,而且在
template<class _T1, class _T2>
inline bool
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{
return __x.first < __y.first
|| (!(__y.first < __x.first) && __x.second < __y.second);
}
重点看下其实现:
__x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second)
这个less在两种情况下返回true:
第一种情况:__x.first < __y.first 这个好理解,就是比较key,如果__x的key 小于 __y的key 则返回true。
第二种情况:!(__y.first < __x.first) && __x.second < __y.second
所以需要写一个函数对象来重载相关的库函数即可
typedef pair<string, int> PAIR;
bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) {
return lhs.second < rhs.second;
}
struct CmpByValue {
bool operator()(const PAIR& lhs, const PAIR& rhs) {
return lhs.second < rhs.second;
}
};
到了这一步我们就是万事俱备只欠东风。没错,你猜对了,就是 sort
。
令人兴奋的是,sort算法和map一样,也可以让我们指定元素间如何进行比较,即指定Compare。需要注意的是,map是在定义时指定的,所以传参的时候直接传入函数对象的类名,就像指定key和value时指定的类型名一样;sort算法是在调用时指定的,需要传入一个对象,当然这个也简单,类名()就会调用构造函数生成对象。
这里也可以传入一个函数指针,就是把上面说的第一种方法的函数名传过来。
map<string, int> oWordFrequency;
for (int i = 0; i < vWordsList.size(); i++)
oWordFrequency.insert(pair<string, int>(vWordsList[i], vWordsListValue[i]));
vector<PAIR> vWordTop(oWordFrequency.begin(), oWordFrequency.end());
sort(vWordTop.begin(), vWordTop.end(), CmpByValue());
综上我们就跑通了全部的技术难点。之后的文件流写入,只不过是毛毛雨的东西。
4.0 性能测试
既然需要性能测试,那就暴力一点。于是从网上找了一篇纯英小说《老柳树 - The Old Willow-tree》
根据测试结果,我们大概用了 2.916s,使用了 1.7MB 内存
5.0 心路历程与收获
其实这次作业的目的与内容完全不符。倘若这是一个真实开发情景当中项目的话,PSP或许更加能适合。但若单就这个作业而言,我从设计到功能的实现以及接口的封装可能只花了3~4个小时的时间。PSP表格各项任务的时间并不能很好很正确的统计。
而且在这种可以独立一个人完成的作业当中,各个步骤与阶段之间根本没有明确的界限,完全就像是自然而然的编程。我看到了这个题,于是产生了思路,开始试着敲代码;在敲代码当中可能忘记了具体的需求,又返回去查看;或者遇到了技术上的问题,开始冲浪解决方法,然后继续编程或许突然发现原本的函数可以用结构更加紧密的类来设计编程。这一切就好像是 水到渠成。
所以说目前并没有体会到PSP表格或者说这种开发模式的好处,更加的带给我的而是将简单的问题复杂化的感觉,或许在之后的多人合作中能有更好更丰富的理解
6.0 PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 10 | 7 |
Development | 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 30 | 40 |
• Design Spec | • 生成设计文档 | 30 | 30 |
• Design Review | • 设计复审 | 20 | 25 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
• Design | • 具体设计 | 120 | 60 |
• Coding | • 具体编码 | 240 | 120 |
• Code Review | • 代码复审 | 30 | 30 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 30 |
Reporting | 报告 | ||
• Test Repor | • 测试报告 | 40 | 30 |
• Size Measurement | • 计算工作量 | 20 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 10 |
合计 | 660 | 415 |