软件工程
这个作业属于哪个课程 | 软件工程班级 |
---|---|
这个作业要求在哪里 | 202103226-1 编程作业要求 |
这个作业的目标 | 初步学会码云和Github、git的使用以及通过工程软件进行编程 |
学号 | 20188424 |
我的仓库 | 码云项目地址 |
1、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 45 | 30 |
• Estimate | • 估计这个任务需要多少时间 | 1600 | 1200 |
Development | 开发 | 900 | 600 |
• Analysis | • 需求分析 (包括学习新技术) | 300 | 200 |
• Design Spec | • 生成设计文档 | 150 | 100 |
• Design Review | • 设计复审 | 50 | 50 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 20 |
• Design | • 具体设计 | 20 | 50 |
• Coding | • 具体编码 | 10 | 10 |
• Code Review | • 代码复审 | 150 | 200 |
• Test | • 测试(自我测试,修改代码,提交修改) | 90 | 200 |
Reporting | 报告 | 20 | 20 |
• Test Repor | • 测试报告 | 20 | 30 |
• Size Measurement | • 计算工作量 | 20 | 20 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 10 |
合计 | 3425 | 2730 |
3、解题思路描述
(1)首先我们需要将指定的文件中的内容读取出来,我采用的是FILE指针的方法。
(2)然后就是按照题目所给需求来,基本上是每个要求定义了一个函数来满足相应要求。
(3)比较难的是单词的判断与高频率单词输出,在判断是否为单词时我分了情况讨论:前一个字符是分隔符,当前的为分隔符时,不做处理;前一个字符是分隔符,当前为数字时,继续往后读,直到再次读到分隔符,则跳出;前一个字符是分隔符,当前为字母时,记录连续的字母个数,当个数大于等于4时,就认为找到一个单词并且将其记录到数组中,为记录频率准备,在这其中还需判断是否有数字的存在,有的话就要丢弃。
(4)对于高频词我用一个二位数组存储它的频率,在找到一个最大频率的词时取出单词,同时将该二维数组的频率置0,为下一次判断避免不会出现重复的单词。
4、代码规范的链接:制定的代码规范
5、计算模块接口的设计与实现过程
该实现程序开始时,我是直接用一个.cpp文件写的,没有拆开,写好后我才开始将它拆分为四个头文件(fengechudanci.h、jisuanhangshu.h、bxyjtjxtdc.h、shuchudanci.h)和一个主函数(WordCount.cpp),整个流程就是通过fengechudanci.h这个分割头文件将字符串分割,然后在通过shuchudanci.h头文件进行输出高频单词,我觉得我最核心和最巧妙的部分是下面的代码,shuchudanci.通过题目要求使用分支结构逐步分割字符串,shuchudanci.h运用一个二维数组存放记录单词位置的数和单词频率数,解释看下面代码中的注释,完整代码见码云(有头文件的注释)。
shuchudanci.h
#pragma once
void fenge() {
int x = 0, flag = 1;
if ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= '0' && str[i] <= '9')) {//字母数字符号:A-Z, a-z,0-9能进入
if (y < 4 && (str[i] >= '0' && str[i] <= '9')) {//判断前4个字符中是否有数字
flag = 0;
}
else if (flag == 1) {//在前4个字符没有数字的前提下将字符都输入数组
ctr[x][y] = str[i];
}
y++;
}
else {//其他字符进入
if (y < 4) {//输入的字符下标小于4则不符合题目给出的单词定义,二维数组的行不加,列置0
ctr[x][0] = ' ';
ctr[x][1] = ' ';
ctr[x][2] = ' ';
ctr[x][3] = ' ';
y = 0;
}
if (y >= 4 && flag == 1) {//输入的字符符合要求,则x++
ctr[x][y] = ' ';
x++;
y = 0;
}
else//输入的字符中有数字,则该段字符不符合单词的要求,将数组的列y置0
{
y = 0;
flag = 1;
}
}
}
shuchudanci.h
#pragma once
void dancishuchu() {
int xiabiao = 0, f = 1, max, q = 0, p = 0;
for (int h = 0; h < x - d + 1; h++) {
while (jilu[1][q] == 0) {//跳过记录单词位置为0的比较
q++;
}
max = jilu[1][q];
xiabiao = q;
p = q + 1;
while (jilu[1][p] == 0) {//同上
p++;
}
for (int s = p; s < x - d + 1; s++) {
if (max < jilu[1][s]) {
max = jilu[1][s];//找到单词频率最大的
xiabiao = s;//保存记录该单词位置的下标
}
if (max == jilu[1][s]) {
if (strcmp(ctr[jilu[0][s]], ctr[jilu[0][xiabiao]]) < 0) {//频率相等时比较字典序靠前的单词
xiabiao = s;
}
}
}
fprintf(fp1, "word%d: %s
", f++, ctr[jilu[0][xiabiao]]);
jilu[1][xiabiao] = 0;//输出一个单词,将记录该单词的位置的下标置0
q = 0;
if (f > 10) {//输入前10个
break;
}
}
}
6、计算模块接口部分的性能改进。
调试过程中出现过数组越界,后发现是自己代码书写有问题,写正确后就不报错了,然后在不断的修改下,数据能更快的显示出来。
7、计算模块部分单元测试展示
对于测试这方面了解的不多,也缺少编写测试程序的能力,但是我会多多调试代码验证其正确性。下面是一些测试截图,就不展示过多测试用例了。
如需验证,放在VS中,要通过项目 -> 属性 -> C/C++ -> 预处理器 -> 预处理器定义 -> 编辑,在框内写入 _CRT_SECURE_NO_WARNINGS才能运行,或者通过DEV直接就能验证。(如出现bug,可能是我有没考虑到的地方吧,请忽略)
8、计算模块部分异常处理说明
在编写过程中出现了许多问题导致程序运行不了,但都通过网上搜索或者调试改进了,在实现过程中只想着做出来没有留下异常截图。
9、在附录提供的PSP表格记录下你在程序的各个模块上实际花费的时间
见上面1中PSP表格
10、心路历程与收获
通过今天几天的学习,让我体会到了长期打代码的重要性,如果很久不编程,再来编程就会慢很多,很多东西也会忘记。同时明白了在写之前先将代码的架构讨论清楚,需要哪些函数,方法,需要定义哪些变量等,这样在写代码的时候思路就会很清晰。测试过程多使用一些测试案例很容易就检差出了一些问题等,然后改进,大大提高了代码的正确性以及稳定性。