实验要求
- 对源文件(*.txt,*.cpp,*.h,*.cs,*.html,*.js,*.java,*.py,*.php等,文件夹内的所有文件)统计字符数、单词数、行数、词频,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。
- 使用性能测试工具进行分析,找到性能的瓶颈并改进
- 对代码进行质量分析,消除所有警告
- 设计10个测试样例用于测试,确保程序正常运行(例如:空文件,只包含一个词的文件,只有一行的文件,典型文件等等)
- 使用Github进行代码管理
- 撰写博客
前期准备
需求分析
本次作业要求对任意文件或者特定目录下所有文件中的字符、单词、词组做相应的统计分析,并将统计结果输出到result文件中。其中主要有以下需要特别注意的:
- 质量要求高,要求使用VS分析热行,提高程序性能,并且要做到没有“警告”;
- 要求跨平台;
- 甲方的要求很“反人类”,不容易理解;
- 博客的撰写、作业进程的记录与分析等。
代码规范
VS会自动换行,加空格之类的,在此基础上根据我个人的习惯,结合之前看的一些书,制定了以下规范:
- 变量的定义,如果涉及到2个单词,第一个单词首字母大写,第二个单词首字母小写;
- 对于每个代码块,使用 4 空格或等长的 Tab 缩进;
-
定义变量不同行;
花括号独占一行; -
不应该有两个连续的空行;
-
main
函数的返回值类型必须是int
,可以省略return 0;
传参时,应该根据实际需要使用「引用」、「
const
引用」和「值传递」,比如定义bool cmp的时候一定要使用const;-
应该尽量少使用全局变量。
PSP表格----随着进度会随时更新
PSP2.1 |
任务内容 |
计划完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
30 |
30 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
30 |
30 |
Development |
开发 |
650 |
- |
Analysis |
需求分析 (包括学习新技术) |
0 |
0 |
Design Spec |
生成设计文档 |
30 |
- |
Design Review |
设计复审 (和同事审核设计文档) |
10 |
- |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
20 |
20 |
Design |
具体设计 |
40 |
40 |
Coding |
具体编码 |
400 |
- |
Code Review |
代码复审 |
100 |
- |
est |
测试(自我测试,修改代码,提交修改) |
50 |
- |
Reporting |
报告 |
240 |
- |
Test Report |
测试报告 |
60 |
- |
Size Measurement |
计算工作量 |
30 |
- |
Postmortem & Process Improvement Plan |
事后总结 ,并提出过程改进计划 |
150 |
- |
Summary |
合计 |
920 |
- |
设计思路
- 根据输入的目录或文件名将所有的文件路径以及文件夹保存在vector<string>,对每个文件依次进行统计。
- 将每个文件的字符流读入一个string,从头到尾进行处理。
- 单词、词组信息利用C++中的unordered map实现。定义结构体strint,存储字典序最小的str以及对应的频率。对于单词来说,采用unordered_map<string, strint> Wordfre,其中第一个str是去除了单词后缀数字并且全部转化为小写字母的串,便于hash。对于词组来说,采用数据结构unordered_map<string, int> Phrasefre来存储,其中string是2个单词的连接,其中用 _来划分。词组在输出时,拆分,利用Wordfre中的信息更新字母的大小写信息。
- 判断统计单词的实现如下:依次读取string的字符,结合已经输入的字符的信息,判断能否成词。细节见代码。一旦成词,清空之前已经输入的信息。
- 判断统计词组的实现如下:结合当前的单词,和上一次的单词Lastword结合成为词组
- 关于Top10单词的获得, 这里采用C++的优先队列,队列维持出现最频繁的10个元素,时间复杂度O(nlogk).