• 福大软工1816 · 第五次作业


    结队同学链接

    本作业博客的链接

    Github地址

    • 分工明细:

    蒋熊:负责WordCount的升级以及python学习,添加新的命令行参数的重要支持(权重词频统计,词组统计等新功能设计)、
    黄志铭:负责python的学习,自定义输入输出文件,VS上词频、行数等设计,性能测试。

    • PSP:
    PSP2.2 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 100 200
    · Estimate · 估计这个任务需要多少时间 10 10
    Development 开发 500 800
    · Analysis · 需求分析 (包括学习新技术) 240 300
    · Design Spec · 生成设计文档 240 200
    · Design Review · 设计复审 20 30
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 30
    · Design · 具体设计 70 50
    · Coding · 具体编码 0 0
    · Code Review · 代码复审 0 0
    · Test · 测试(自我测试,修改代码,提交修改) 0 0
    Reporting 报告 40 100
    · Test Repor · 测试报告 50 20
    · Size Measurement · 计算工作量 15 10
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 80
      合计 1355 1830
    • 解题思路描述与设计实现说明

     拿到题目的第一时间就是想到上一次个人作业的单词统计,这次结对作业的代码即是对上次作业的一点拓展,首先是输入是爬取的论文标题和摘要,数据量比较大,因此在思考问题的解决方案时首先应该考虑时间和空间的优化算法,其次是本次时词组频率统计而不是单词频率,因此上次使用map来记录的方式就将修改,而如何快速获得词组和权重累计就成为关键点。

    至于字符、单词数和行数的统计比较简单,与上次无差异就不再做介绍,因此接下来主要介绍词组频率统计部分的代码:

           因为词组将被标题和摘要隔开,且遇到’ ’也将被阻隔,因此在考虑时就可以采用分行处理,提取词组,与现有统计词组比较,若出现过相同词组,则权重累加,若无出现过,则新增词组存入,最后排序输出前十即可。而在分行处理时,考虑采用结构体存储单个词组,对每行单词进行预处理,逆序dp,处理每一个单词的连续词组的最后一个单词下标(即如果出现多个单词,中间只含分隔符,不含不合法单词,则称为连续词组,若只有该单词本身则记录自己下标),否则遇见非法单词,记为-1,如此进行正序搜索,如若某合法单词记录的连续词组最后一个单词下标-自身下标+1>=词组要求长度,则说明以此单词为起点存在合法词组,则记入,按上述方法累加权重或新增词组,若遇见-1或是长度不满足需要,则说明是不合法词组,无需操作,最后自定义排序函数cmp进行排序输出即可。

    python:

    复制代码
    #-*- coding: utf-8 -*-
    import time
    import re
    import random
    import requests
    
    # url = 'http://openaccess.thecvf.com/CVPR2018.py 
    
    '
    
    #这个headers信息必须包含,否则该网站会将你的请求重定向到其它页面
    headers = {
        'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Encoding':'gzip, deflate, sdch',
        'Accept-Language':'zh-CN,fr-FR,zh,en-us;q=0.8',
        'Connection':'keep-alive',
        'Host':'www.openaccess.thecvf.com 
    
    ',
        'Referer':'http://openaccess.thecvf.com/CVPR2018.py 
    
    ',
        'Upgrade-Insecure-Requests':'1',
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
    }
    
    if __name__ == '__main__':
        #将爬取结果存储到results.txt文件中
        with open('results.txt','a+') as res:
            #通过url_results.txt读取链接进行访问
            with open('url_results.txt') as f:
    
                for reurl in f:
                    print("正在读取:"+reurl)
                    response = requests.get(reurl.replace('
    ',''), headers=headers)
                    all_content = response.text.replace('
    ', '').replace('	', '').replace('
    ', '').replace(' ', '')
                    re_title = r'<divid="papertitle">(.*?)</div>'
                    title = re.findall(re_title ,all_content, re.S | re.M)
                    re_abstract = r'<divid="abstract">(.*?)</div>'
                    abstract = re.findall(re_abstract, all_content, re.S | re.M)
                    res.write("Title: "+title[0]+'
    ')
                    res.write("Abstract: " +abstract[0]+'
    ')
                    res.flush()
                    res.write('
    ')
                    res.write('
    ')
                    time.sleep(random.randint(1, 3))
    复制代码

    程序代码:

    复制代码
    int lines_counts()    //计算非空行 
    {
        ifstream rf("result(1).txt");
        freopen("output1.txt","w",stdout);
        if (!rf) {
            cout << "open file failed. trying open default file:input.txt" << endl;
        }    
            string Str;
        char c;
        int lines=0;
            while (getline(rf, Str)) 
        {
          if(Str!="" && ((Str[0] >= 32 && Str[0] <= 126) || Str[0] == 9 || Str[0] == 10)  && !(Str[0] >= 48 && Str[0] <= 57) )
           {     
           //cout<<Str<<endl;  
               lines++;  
          //cout<<lines<<endl;
            }   
        }
            rf.close();    
         return  lines;
    
    }
    复制代码

          在计算非空行的时候,逐行读取,判断是否是空行符、数字、以及非ASCII字符。python在爬取过程中有遇到非ASCII字符,所以在这里加以判断。

    复制代码
    sort(rr,rr+x,cmp);
        int mi = min(10, x);     
        int d;
        rep(i, 0, mi)    
        {
            fprintf(os,"<");
            printf("<");
            rep(j, 0, m)
            {
                char sq[50];
                int yy = rr[i].s[j].length();
                for(d = 0; d < yy; d++)
                sq[d] = rr[i].s[j][d];
                sq[d] = '';
                fprintf(os,"%s ",sq);
                printf("%s ",sq);
            }
            fprintf(os,">: %d
    ",rr[i].val);
            printf(">: %d
    ",rr[i].val);
        }
    复制代码

    其中的mi=min(10, x)主要是对结果词频的判断,如果词频小于10,则输出所有词频,反之则输出前10个词频。

    复制代码
        if(s == "Title:")
            {
                v1 = 10;
                h = 1; 
                continue;
            }
            
            else if(s == "Abstract:")
            {
                v1 = 1;
                //flf = false;
                continue;
            }
    复制代码

    在赋予权值的时候,对权值的区分加以区别。

    复制代码
        len = s.length();
            //cout << "s = " << s << endl;
            if(len < 4)
            {
                ww[h++].flag = false;
                //cout << "ccc   " << " h = " << h-1 << "    flag = " << ww[h].flag << endl;
                continue; 
            }
            w(len >= 4)
            { 
                k = 0;
                w(len >= 4 && (s[k] == '(' || s[k] == ')' || s[k] == '*'))
                {
                    k++;
                    len--;
                }
                s = s.substr(k);
                i = 0;
                k = 0;
                
                flag = false;
                fflag = false;
                w(((s[i] >= 65 && s[i] <= 90) || (s[i] >= 97 && s[i] <= 122)) && i < len && !fflag)
                {
                    k++;
                    if(s[i] >= 65 && s[i] <= 90)
                    s[i] = s[i] + 32;
                    i++;
                    if(k == 4)
                    {
                        flag = true;
                        break;
                    }
                }
                if(flag)
                {
                    w((s[i] >= 48 && s[i] <= 57) || (s[i] >= 65 && s[i] <= 90) || (s[i] >= 97 && s[i] <= 122))
                    {
                        if(s[i] >= 65 && s[i] <= 90)
                        s[i] += 32;
                        k++;
                        i++;
                    }
                    if(k == len)
                    {
                        //cout << "aaa" << endl;
                        ww[h].s = s;
                        ww[h].flag = true;
                        //cout << "bbb   " << " h = " << h << "    flag = " << ww[h].flag << endl; 
                        ww[h].val = v1;
                        g = 0;
                        h++;
                        len -= k;
                        break;
                    }
                    
                    else
                    {
                        if(k >= 4)
                        {
                            s1 = s.substr(0, k);
                            //cout << "bbb" << endl;
                            ww[h].s = s1;
                            ww[h].flag = true;
                            //cout << "aaa   " << " h = " << h << endl; 
                            ww[h].val = v1;
                            h++;
                            //cout << "s1 = " << s1 << endl;
                        }
                        
                        s = s.substr(k);
                        //cout << "s2 = " << s << endl;
                        len = len - k; 
                    }
                }
                else
                {
                    len -= k;
                    ww[h++].flag = false;
                    //cout << "ddd   " << " h = " << h-1 << "    flag = " << ww[h].flag << endl; 
                    s = s.substr(k);
                    k = 0, i = 0;
                    w((s[i] <= 65 || (s[i] >= 91 && s[i] <= 96) || s[i] >= 123) && i < len)
                    {
                        k++;
                        i++;
                    }
                    if(s[i-1] < 48 || (s[i-1] > 57 && s[i-1] < 65) || (s[i-1] >= 91 && s[i-1] <= 96) || s[i-1] > 122)
                    fflag = false;
                    else fflag = true;
                    if(fflag)
                    {
                        w(((s[i] >= 65 && s[i] <= 90) || (s[i] >= 97 && s[i] <= 122) || (s[i] >= 48 && s[i] <= 57)) && i < len)
                        {
                            k++;
                            i++;
                        }
                    }
                    if(k)
                    {
                        s = s.substr(k);
                        len -= k;
                    }
                }
            }
    复制代码

    这个代码段是对单词进行统计,采用结构体存储单个词组,对每行单词进行预处理,逆序dp,得到下标。然后遍历单词,如果是符合m的词组,就记入,否则遇见非法单词,记为-1,如此进行正序搜索。

    共计爬取:979篇,以下结果是取前21篇论文进行的测试结果:

    • VS的性能分析:

    • 遇到的代码模块异常或结对困难及解决方法:

                   这次代码的思路一开始就有,写得还算是比较顺利,但是因为代码在Dev-c++上写,所以后续要换到VS上测试的时候,就出现要改的东西很多,吸取下教训,然后就开始学习怎么在VS上面写代码,在百度上百度了好久没发现,结果后来在博客中看到关于C++类的规范写法,才一目了然。目前已经搞清楚怎么使用VS写C++的程序及其类。

                   另外,有一点需要提及的是,由于刚开始在Dev上写的读入文件形式是以字符读入,而VS刚接触,在里面打开文件好像是采用getline比较合适,所以要改起来比较多,提交的时间快到了,后续再继续改吧。

    • 队友评价:

                   队友很可以啊,志铭做的vs封装,我一开始用的devc++的编译器,然后肯定没法提交,志铭各种查,然后弄得VS,有他我很放心。

        还有在省题的时候难点就只是词组频率统计那个,我们在写的时候呢,两个人就想了很多设想,然后分开各种试,就算是有划分分工,但是我们也没真的1认真,也还是互相帮忙,所以这队友特别靠谱,不管最后做的好不好,过程轻松,一个interesting的人。

         

    • 学习进度条
      第N周新增代码(行)累计代码(行)本周学习耗时(小时)累计学习耗时(小时)重要成长
      1 256 256 20 20 学习git,然后就是c++一些数据结构的温习
      2 82 338 10 30 优化代码吧
      3  0 20  50  学习第三和第八章,再就是新工具的使用
      4 508 846 30 80 学习python,以及VS
  • 相关阅读:
    Javascript作用域研究(with)
    Javascript判断object还是list/array的类型(包含javascript的数据类型研究)
    Javascript两个感叹号的用法(!!)
    Javascript中两个等于号和三个等于号的区别(==/===)
    IIS配置MP3/MP4/OGG/flv等资源文件访问
    生成GUID唯一值的方法汇总(dotnet/javascript/sqlserver)
    记录一次:微信支付申请时,网站不通过/统一驳回的问题解决方法
    C# 扩展系统类方法
    Javascript获取div真实高度
    Jquery获取offsetHeight
  • 原文地址:https://www.cnblogs.com/jxdbky/p/9769532.html
Copyright © 2020-2023  润新知