2018软工实践做业五之结对做业2

博客连接

刘浩:http://www.javashuo.com/article/p-wheluewc-bw.html
后敬甲:http://www.javashuo.com/article/p-vggafcmt-ds.htmlhtml

具体分工

后敬甲:对爬取文本的字符统计、有效行统计、单词统计;
刘浩:文章的爬取、附加题、词频统计、博客主要撰写;python

Github项目地址

https://github.com/tsf2016/pair-projectc++

PSP表格

解题思路描述与设计实现说明

爬虫使用

使用python语言实现,其中使用到了requests库和beautifulsoup库,主要使用bs的.select函数选择html中所须要的标签的id,class属性,以找到并获取对应的信息git

代码组织与内部实现设计(类图)

主要流程图以下
github

说明算法的关键与关键实现部分流程图

处理自定义输入

简单使用条件语句逐个判断输入的参数,分析其对应的功能,并给出可能发生的错误分析算法

while (argv[p] != NULL) {
        if (argv[p][0]!= '-') {
            printf("错误输入格式\n");
            return -1;
        }
        else if(argv[p][1]=='i'){
            if (argv[p + 1] == NULL) {
                printf("缺乏输入路径\n");
                return -1;
            }
            ipath = argv[p + 1];//输入.txt文件的路径
            p=p+2;
            continue;
        }
        else if (argv[p][1] == 'o') {
            if (argv[p + 1] == NULL) {
                printf("缺乏输出路径\n");
                return -1;
            }
            opath = argv[p + 1];//输出.txt文件的路径
            p = p + 2;
            continue;
        }
        else if (argv[p][1] == 'n') {
            if (argv[p + 1] == NULL) {
                break;
            }
            if (isdigit(argv[p + 1][0]) == NULL) {
                p++;
            }
            else {
                diy = atoi(argv[p + 1]);//词频输出个数
                p = p + 2;
            }
            continue;
        }
        else if (argv[p][1] == 'm') {
            if (argv[p + 1]== NULL) {
                break;
            }
            if (isdigit(argv[p + 1][0]) == NULL) {
                p++;
            }
            else {
                if (atoi(argv[p + 1]) < 2 || atoi(argv[p + 1]) > 10){
                    printf("错误词组长度");
                    return -1;
                }
                cizulen = atoi(argv[p + 1]);//词组长度
                p = p + 2;
            }
            continue;
        }
        else if (argv[p][1] == 'w') {
            if (argv[p + 1] == NULL || (atoi(argv[p + 1])!=1 && atoi(argv[p + 1])!=0)) {
                printf("错误权重\n");
                return -1;
            }
            weight = atoi(argv[p + 1]);//词频权重
            p = p + 2;
            continue;
        }
        else {
            printf("错误参数\n");
            return -1;
        }
    }

统计字符数

int character(char* path) {
    /*
    ifstream 读取文件路径
    逐个读取字符数,统计读入的全部字符
    将全部字符链接后按分割符进行分割,将一个个子字符串放入vector中
    /*
    for (vector<string>::size_type i = 0; i != split.size(); ++i) {
    //逐个读入子字符串,计算子字符串为“Title“的次数,
        string key = split[i];
        if (i+2<=split.size()&&split[i + 1] == "Title"&&key.size() <= 3) {
            //字符数还要减去Title前的文章编号
            count = count - key.size()-1;
            //cout << count << endl;
        }   
        if (m1.count(key) == 0)
        {
            m1.insert(pair <string, int>(key, 1));
        }
        else
        {
            m1[key]++;
        }
    }
    /*
    由于Title不会在正文(须要统计的范围)中出现,
    而每个Title对应着一个一样不须要统计的Abstract,按照题意每一篇文章要减去17个字符
    */
    count = count - m1["title"] * 17;
    return count;
}

统计单词数

与统计字符数原理类似,也是算出总的单词数而后再减去出现的Title和Abstract的次数,还有两论文之间的换行网络

统计词频输出

附加题设计与展现

  • 设计的创意独到之处
    • 分析论文列表中各位做者之间的关系,论文A的第一做者可能同时是论文B的第二做者,不一样论文多位做者之间可能存在着联系
    • 对数据的图形可视化作出一些努力,好比对上一条功能能够造成关系图谱
  • 实现思路-
    利用爬虫获取每篇文章的做者信息,存入.txt文件中,再利用excel读取.txt信息,按照文章次序和第一做者,第二做者这样的排序来整理,以后再利用gephi工具读取要处理的excel文件,利用该工具自带的功能实现做者之间的关系网络力向图
  • 实现成果展现
    做者权重

    效果局部图

关键代码解释

int character(char* path) {
    /*
    ifstream 读取文件路径
    逐个读取字符数,统计读入的全部字符
    将全部字符链接后按分割符进行分割,将一个个子字符串放入vector中
    /*
    for (vector<string>::size_type i = 0; i != split.size(); ++i) {
    //逐个读入子字符串,计算子字符串为“Title“的次数,
        string key = split[i];
        if (i+2<=split.size()&&split[i + 1] == "Title"&&key.size() <= 3) {
            //字符数还要减去Title前的文章编号
            count = count - key.size()-1;
            //cout << count << endl;
        }   
        if (m1.count(key) == 0)
        {
            m1.insert(pair <string, int>(key, 1));
        }
        else
        {
            m1[key]++;
        }
    }
    /*
    由于Title不会在正文(须要统计的范围)中出现,
    而每个Title对应着一个一样不须要统计的Abstract,按照题意每一篇文章要减去17个字符
    */
    count = count - m1["title"] * 17;
    return count;
}

性能分析与改进

减小不一样功能对读入字符后的操做,如只记录字符数的话就不须要将字符串统一转小写,若只记录单词数的话就不须要放入map中等等
* 性能分析图

* 调用最大资源的函数
函数

单元测试

* TestMethod1:空文本
* TestMethod2:单字符文本
* TestMethod3:全空格文本
* TestMethod4:非字母与数字文本
* TestMethod5:单词所有大写文本
* TestMethod6:单词数字开头文本
* TestMethod7:最后一行有换行
* TestMethod8:单词长度小于4
* TestMethod9:汉字文本名
* TestMethod10:无输入

贴出Github的代码签入记录

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

  • 困难:
    一开始负责所有的文本处理模块,遇到许多算法的困难,最后也独立实现了所有的功能,可是词频统计使用告终构体结点优先队列来对词组排序,算法时间复杂度太大,致使存在数据量过大就会超时的问题。
  • 解决方案:
    采用了刘浩同窗的版本,使用了c++的stl容器,解决了超时的问题。
  • 有何收获
    在整个算法实现过程当中,使用了switch语句实现了有穷自动机、哈希算法存储词组、优先队列对结构体结点排序,对之前的知识有了个回顾;对于存在问题的词频统计功能,经验上应该更仔细地阅读需求、估计时间复杂度,算法上学习了c++的map容器和vector容器。
  • 评价你的队友
    有很强的快速学习能力,专业能力强,学习的态度和方法都是我学习的榜样。

学习进度条

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
4 0 340 5 25 Leangoo工具的学习
5 300 640 15 40 哈希算法、优先队列、结构体等c++算法复习

    

参考

[关系图谱] 一.Gephi经过共线矩阵构建知网做者关系图谱
https://blog.csdn.net/eastmount/article/details/81746650工具

相关文章
相关标签/搜索