福大软工1816 · 第二次作业——单词词频统计

一、Fork的同名仓库的Github项目地址

github项目地址

二、PSP表格

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划00
· Estimate· 估计这个任务需要多少时间360480
Development开发00
· Analysis· 需求分析 (包括学习新技术)240240
· Design Spec· 生成设计文档00
· Design Review· 设计复审00
· Coding Standard· 代码规范 (为目前的开发制定合适的规范)00
· Design· 具体设计10
· Coding· 具体编码8080
· Code Review· 代码复审00
· Test· 测试(自我测试,修改代码,提交修改)510
Reporting报告60120
· Test Repor· 测试报告00
· Size Measurement· 计算工作量1010
· Postmortem & Process Improvement Plan· 事后总结, 并提出过程改进计划1010

三、解题思路描述

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()中会调用其他三个函数。
    1474284-20180910210609446-1992256357.png

五、代码测试

  • 读取的文本与程序放在同个文件夹
    1474284-20180910210804077-1023416416.png
    1474284-20180910210811542-773605814.jpg
  • 代码执行后创建result文本
    1474284-20180910210839657-1327216652.png
    1474284-20180910210927347-572959070.png

六、性能分析

1474284-20180910211019933-1668642795.png
消耗最大的函数
1474284-20180910211033034-223982147.png

七、代码

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);
}

八、异常处理

1474284-20180910212147268-1789271594.png

  • 执行过程中多次出现过类似的问题,例如此处需要使用_itoa_s等,因为在vs下要使用安全函数。

九、总结

在这次的作业中,大部分时间花在代码上,因为并没有做过类似这样的项目,但在这次项目我学习到了许多新的函数用法 ,以及当程序执行报错时候应当如何解决,虽然感觉在这次作业中还有用许多笨办法,但是也算有所进步,希望能够在接下来的项目中越做越好。

转载于:https://www.cnblogs.com/kkyblog/p/9606429.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值