一、Fork的同名仓库的Github项目地址
二、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 0 | 0 |
· Estimate | · 估计这个任务需要多少时间 | 360 | 480 |
Development | 开发 | 0 | 0 |
· Analysis | · 需求分析 (包括学习新技术) | 240 | 240 |
· Design Spec | · 生成设计文档 | 0 | 0 |
· Design Review | · 设计复审 | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 0 | 0 |
· Design | · 具体设计 | 10 | |
· Coding | · 具体编码 | 80 | 80 |
· Code Review | · 代码复审 | 0 | 0 |
· Test | · 测试(自我测试,修改代码,提交修改) | 5 | 10 |
Reporting | 报告 | 60 | 120 |
· Test Repor | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 10 | 10 |
三、解题思路描述
1.文本读入功能:在项目文件夹下创建test.txt的文本,利用fopen,fread函数来读取文件。
2.字符统计功能:利用fseek将指针放入文本末尾后用ftell来返回末尾指针到开头的距离即字符数。
3.行数统计功能:读取文件时候是一个个字符读取的,将存储文件的字符数组遍历一遍看是否有出现\n,出现则行数+1。
4.单词统计功能:利用strtok函数来切割文本,将每个分割好的单词存入*p,遍历并筛选判断字符串长度,再判断前四位是否是字母,若出现大写字母则通过ascii码+32来转化为小写字母。创立一个map(string,int)容器,通过count来判断该单词是否出现过,若未出现则insert一个新的项,若出现过了则在原来项中的int里++。
5.频率排序功能:将map中的string,int分别存入数组中,先排序int,再排序string,从而达到按序输出。
6.文本写入功能:通过fopen,fwrite自动创建一个result文本,并将需要的功能写入result文本。
四、设计实现过程
- readtxt():用于读取test.txt文件
- main():用于统计字符数、行数、词频数
- sort():用于排序前十词频数
- write():用于将结果写入result.txt文件
main()中会调用其他三个函数。
五、代码测试
- 读取的文本与程序放在同个文件夹
- 代码执行后创建result文本
六、性能分析
消耗最大的函数
七、代码
1.读取文件
void readtxt() //读取文件
{
cin >> test;
FILE *fp;
errno_t err;
err = fopen_s(&fp, test, "r"); //读取test文件
fseek(fp, 0, SEEK_END);//将指针放到文件的末尾
charactersnum = ftell(fp);//返回指针末尾到开头的值 即字符长度
rewind(fp); //还原 将指针放回开头
fread(s, charactersnum, 1, fp);
}
2.判断单词是否合理并记录合理单词
while (p)//遍历单词 并把单词放入数组wordsrep 频率放入数组numrep
{
wordsmid = p;
strcpy_s(words, wordsmid.c_str()); //将字符串转为字符数组
b = wordsmid.length(); //判断字符串的长度
for (j = 0; j <= 3; j++)//判断该单词是否符合前四位为字母
{
if (words[j] >= 'a' && words[j] <= 'z')
pos = 1;
else if (words[j] >= 'A' && words[j] <= 'Z')
{
words[j] = words[j] + 32;
wordsmid = words;
pos = 1;//将所有大写字母转换为小写字母
}
else
{
pos = 0;
break;
}
}
if (b >= 4 && pos == 1)//判断是否该单词不低于四个符号切前四位是字母
{
wordsnum++;
if (m1.count(wordsmid) == 0)
{
m1.insert(pair <string, int>(wordsmid, 1));
wordsrep[i] = wordsmid;
numrep[i] = 1;
i++;
} //若该单词未记录,则在map中创建一个新的项
else
{
for (j = 0; j <= i; j++)
{
if (wordsrep[j].compare(wordsmid) == 0)
{
numrep[j] = numrep[j] + 1;
}
}
m1[wordsmid]++;
} //若该单词已记录,则将该单词记录的map里的int数量+1
}
p = strtok_s(NULL, d , &buf);
}
3.频率排序
void sort()
{
for (j = 0; j <= i - 1; j++)
{
for (k = i - 2; k >= j; k--)
{
if (numrep[k + 1] > numrep[k])
{
t1 = numrep[k + 1];
numrep[k + 1] = numrep[k];
numrep[k] = t1;
t2 = wordsrep[k + 1];
wordsrep[k + 1] = wordsrep[k];
wordsrep[k] = t2;
}
if (numrep[k + 1] == numrep[k])
{
if (wordsrep[k + 1] < wordsrep[k])
{
t2 = wordsrep[k + 1];
wordsrep[k + 1] = wordsrep[k];
wordsrep[k] = t2;
t1 = numrep[k + 1];
numrep[k + 1] = numrep[k];
numrep[k] = t1;
}
}
}
}
}
4.写入文件
void writetxt() //输出文件
{
FILE *fp1;
errno_t err;
err = fopen_s(&fp1,"result.txt", "w");
fwrite(res_c, res.length(), 1, fp1);
}
八、异常处理
- 执行过程中多次出现过类似的问题,例如此处需要使用_itoa_s等,因为在vs下要使用安全函数。