2018软工实践作业二之个人作业
2018软工作业二之个人项目
- github网址
- PSP表格
- 解题思路
- 刚看到题目,我就思考这个应该使用什么来解决,第一想法是数组,但是后面觉得数组大小拓展不方便,还可能浪费内存,相对而言,链表的内存利用率高,而且容易拓展,不存在越界
- 至于编程语言,肯定是c/c++ ,因为其他的需要不熟悉!
- 最后把题目copy一下,百度一下,参考一下别人的思路,毕竟柯大神说过类似的话 ”在目前最好的基础上改进,改进了你就是top1”,”有参考的为什么不参考呢”。
- 代码设计过程
-
我的想法是有两部分,读取文本和检测字符 + 统计top10并按字母表输出。
-
代码分成两个函数,一个是 readfile(struct word*&head),用来去读文本并且统计统计
characters: number words: number lines: number
另外一个是 sort(struct word*&head),用来挑选出单词中出现频率TOP10的单词。
- 设计实现过程
1.readfile()
基本思想:
1.count记录单词出现的次数,word存储新单词。
2.一个字符一个字符进行判断, 判断前将‘A-Z’转为‘a-z’
判断条件为:
1.如果没有到单词分割位,则将‘a-z’存入临时字串temp[30],
2.如果出现超过30位的单词,则认为文档出错,将这个单词舍去,直到下一个分割符后才重新进行记录。
3.每个单词分割位为非‘a-z’的ASCII码,但是‘-’除外,有些合成单词会使用‘-’
4.汉字不考虑
struct word {
char name[30];
int num;
struct word *next;
};
void readfile(struct word*&head)
{
FILE *fp;
int n = 0,m = 0,sum=0;
if ((fp = fopen("D:\\VSprogram\\ConsoleApplication1\\hao.txt", "r")) == NULL)//读取文本
{
printf("无法打开此文件!\n");
exit(0);
}
char ch, temp[30];
struct word *p;
while (!feof(fp))
{
int i = 0;
ch = fgetc(fp);//读取字符
temp[0] = ' ';
while ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z') || temp[0] == ' '||ch == '\n')
{
if (ch >= 'a'&&ch <= 'z' || ch >= 'A'&&ch <= 'Z')
{
temp[i] = ch;
i++;
n++;//字符计算
}
if (ch == '\n') sum++;//行数计算
ch = fgetc(fp);
if (feof(fp)) break;
}
temp[i] = '\0';
p = head->next;
while (p)
{
if (!_stricmp(temp, p->name))
{
p->num++; break;
}
p = p->next;
}
if (!p&&temp[0] != '\0')
{
p = new word;
m++;//单词计算
strcpy_s(p->name, temp);
p->num = 1;
p->next = head->next;
head->next = p;
}
/* if(!p&&temp[0] == '\n')
{
sum++;
p->next = head->next;
head->next = p;
}*/
}
printf("characters: %d\n", n);
printf("words: %d\n",m);
printf("lines: %d\n", sum+1);
}
2.sort()
基本思想:将所有单词统计形成链表之后,需要对链表的top10进行统计。
基本思路:
1.用Top指针指引head指针所指引的原链表的前10项。用p指针指向第11项
2.Top的尾指针指为空
3.对top引导的十项使用排序算法进行排序。
排序算法基本思想:
1.用计数器和指针,记录指向从当前项到末尾项的最高count,然后用一个指针指向这个节点,最后和当前项进行节点内容数据进行交换,使得各节点的物理地址不发生变化。
2.从第11项开始,将每个节点的记录count同前十个进行比较,如果大于当前项则进行节点的插入,同时将最后一个节点删除。需要记录的节点指针位置有:当前节点的前一项以及top10节点中的第十项,主链表的当前项。
void sort(struct word*&head)
{
struct word *q;
int a[10], i;
for (i = 0; i < 10; i++)
a[i] = 0;
//top10
for (i = 0; i < 10; i++)
{
q = head;
while (q != NULL)
{
if (q->num > a[i])
a[i] = q->num;
else
q = q->next;
}
q = head;
while (q != NULL)
{
if (a[i] == q->num)
{
q->num = 0;
printf("%s:", q->name);
printf("%d\n",a[i]);
//puts(q->name);
break;
}
else
q = q->next;
}
}
}
3.单元测试
- 性能分析
大概花费花费30min在性能分析上,main()函数连续10000执行的性能分析图如下:
大致可以看出,fopen和fgetc耗时较多
函数的性能分析图
- 函数单元测试
-
心得体会
这次作业,原本以为只是小试牛刀,想不到是大伤筋骨。远远低估了软工,这学期其实应该叫做“软工时间”。真的可以占据我百分80的spare time,心态崩了啊!上周末我的“蜗牛神机”又拿去大利嘉维修,两天都没能着手,拿回来还得重装系统和软件。眼看DDL就要了,连续三天爆肝!过程痛苦,结果美好。这次作业,颇有收获:
- 捡起来了git。
- 学会了vs的各种调试分析工具和各种用法如:函数覆盖率、单元测试、性能堪查器、还有dll的封装和使用(虽然后面采用的不是这种封装方式,不过也学到了)。
至于构建之法,很尴尬,书还没买,还没看。等书到了再更新下博客吧。心态崩了啊!!