鱼鱼要早睡

导航

软工实践第二次作业

GitHub


PSP表格

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

解题思路

  • 因为对java不是很了解,所以我选择用“C++”来解决这个作业。因此在拿到作业后,我先去查找了有关“C++”如何读取和输出文件,以及一些相关的头文件。

  • 题目要求的是统计文件内容的字符数、内容的有效行数、以及单词出现频率和匹配的单词个数。

  • 输出格式为:

   characters: number

    words: number

    lines: number

    <word1>: number

    <word2>: number

     ...

在进行统计文件内容字符数时,我想要逐个字符读入这样子方便统计,而在进行统计文件有效行数时,则希望能够按行读取文件,再判断该行是否为有效行数。而在词频统计和统计单词个数上遇到了点问题,感觉这个题很难啊T T,一开始还是没什么思路。后来通过不断查阅资料,以及和同学之间进行交流,尝试使用正则式,通过正则式来筛选题目要求的单词。


设计实现过程

  • 首先明确,将要执行的任务分成三个部分:一个负责统计文件的有效字符个数,一个负责统计文件的有效行数,一个负责词频统计和统计单词个数,最后将结果一起输出文本。

  • 在写函数前首先是要学习如何读取文件。

  • 在查找了相关的资料后,加入了头文件,在统计字符个数的时候采用逐个字符读入的方法(包括空格和回车):infile >> noskipws;

  • 在统计有效行数的时候,读取文件使用了get()函数,采取按行读入,并且循环查找行中是否存在除了空格、换行、回车外的字符,如果存在就跳出循环并且行数+1.

  • 接下来就是匹配查找符合条件的单词,并且统计单词出现的频率。在词频平统计中套用了正则式的模板,逐个查找,并且实现将大写字母转换成小写字母的功能。最后使用了map去统计出现频率最高的十个单词。


代码说明和测试

  • 统计文件内有效字符的个数

    int charcount(string filename)
    {

    int count1 = 0;

    ifstream infile;
    infile.open(filename.data()); //将文件流对象与文件连接起来
    assert(infile.is_open()); //若失败,则输出错误消息,并终止程序运行

    char c;

    infile >> noskipws;//逐个字符读入(包括空格和回车)
    while (infile >> c)
    {

    if (c >= 0 && c <= 255)
    {
    count1++;
    }
    }

    infile.close();//关闭文件输入流
    return count1;
    }

  • 统计单词的个数以及词频统计同时写入文件

    bool findword(pair<string, int> elem1, pair<string, int> elem2)
    {
    return elem1.second > elem2.second;
    }
    void frequency(string filename)
    {
    ofstream output("1.txt", ios::app);//调用ofstream函数创建输出文件:1.txt; ios::app让后来写的内容接在上一次写的结尾

    string s;
    map<string, int> find;
    regex WordPatternreg("[1]{4}[a-z0-9]");//我们要匹配的单词的正则式
    ifstream ifs(filename);//强制读取文件内容
    while (ifs >> s)
    {
    int l = s.length();//
    for (int i = 0; i < l; i++)
    {
    if (s[i] >= 65 && s[i] <= 90)
    {
    s[i] = s[i] + 32;
    }
    }//将大写转换成小写
    const std::sregex_token_iterator end;
    for (sregex_token_iterator wordIter(s.begin(), s.end(), WordPatternreg); wordIter != end; wordIter++)
    {//在一行文本中逐个找出单词
    //cout<<
    wordIter<<endl;//每个单词
    find[*wordIter]++;//单词计数
    }
    }
    ifs.clear();
    ifs.seekg(0);

    vector<pair<string, int>> ci;
    for (map<string, int>::iterator iter = find.begin(); iter != find.end(); iter++)
    {
    ci.push_back(pair<string, int>(iter->first, iter->second));
    }
    sort(ci.begin(), ci.end(), findword);
    int size = 10;

    int count3 = ci.size();//统计数组里单词的个数

    if (output.is_open())
    {

    output << "word:" << count3 << endl;

    if (ci.size() < 10)
    {
    size = ci.size();
    }

    vector<pair<string, int>>::iterator vit;

    for (vit = ci.begin(); vit != ci.begin() + size; vit++)
    {
    output << "<" << vit->first << ">:" << " " << vit->second << endl;
    }
    }
    output.close();
    }


部分测试结果


心得体会

这是第二次实践作业了。说实话,我觉得第二次的实践作业对我来说真的是太难了T T。但是人只有在挫折中才会慢慢成长起来。通过这次实验其实学了很多。以前都知识简简单单敲那种给一个问题写一个程序的代码。而这次除了要编写代码之外,还得学会如何用C++读取和输出文件,如何将代码进行接口封装,当然最重要的是要学习如何百度获取自己所需要的知识。百度真的是万能啊...感慨一下...以前真的很少使用百度学习一些其实课上学不到的东西。比如这次用到的头文件,基本上是上课没有怎么提到过的。真的学会百度非常重要,第一次体会到能够从网上学知识并且能够马上应用到实际。同时真的深切感受到自己的知识点真是太少了,,说实话这次的实践真的是做得挺吃力得...因为vs有点问题...代码之后还会继续修改...说实话这次的实践真的是做得挺吃力得...艰难地成长...


  1. a-z ↩︎

posted on 2018-09-12 21:52  鱼鱼要早睡  阅读(145)  评论(2编辑  收藏  举报