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


    结对队友:何裕捷
    他的博客地址:http://www.cnblogs.com/fdhyj
    他的本次作业地址:https://www.cnblogs.com/fdhyj/p/9769819.html
    Github项目地址:https://github.com/ljjy/pair-project


    分工明细

    何裕捷:在个人项目的基础上改进WordCount,编码实现所有功能
    黄培鑫:学习使用爬虫工具,辅助测试寻找bug,整理撰写博客


    PSP表格

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

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

    1.爬虫使用

    上网搜索了几款爬虫工具,最终选择了“八爪鱼采集器”。
    (这里给出一个八爪鱼采集器入门教程:https://www.bilibili.com/video/av24131288?t=3820)
    对于本次作业,首先我们来到主界面,点击自定义采集下方的立即使用。

    接着选择手动输入在网址中输入网址,然后点击保存网址,接下来就可以开始选择要采集什么数据了。

    经过一会儿等待后八爪鱼采集器内置的浏览器便打开了这个网页,鼠标移动到第一篇论文的标题上,点击。

    此时右侧出现了操作提示,依次点击“选中全部”-“循环点击每个链接”。

    鼠标移动到标题处点击,选择“采集该元素的文本”;再移动到摘要处,选择“采集该元素的文本”。

    选择完要采集的东西之后,点击右上角的“流程”可以进行查看。

    由于作业要求,标题前需加上“Title: ”,则选中字符1点击下方的铅笔状的“自定义数据字段”-“格式化数据”-“添加步骤”-“添加前缀“,在前缀处输入“Title: ”,点击下方的计算可以预览效果,然后点击确定。同理给摘要加上“Abstract: ”的前缀。

    全部设置好了之后,点击“开始采集”-“启动本地采集”就可以愉快地开始采集数据了。

    采集结束后,由于无法直接导出为符合作业格式要求的txt,所以选择导出为excel,再经过一番人工排版之后便形成美妙的result.txt。

    2.代码组织与内部实现设计

    类图:

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

    维护一个n+n-1的队列(n为词组长度),按顺序检索文本,遇到合法单词,压入该单词和单词后的分隔符串,如果队列未满,则什么都不干,如果队列恰好满了,则找到一个词组,此时将队头的合法单词和分隔符串移出队列。遇到非法单词,则直接清空队列。
    流程图:


    关键代码解释

    struct FrequentWord
    {
    	string word;
    	int weight;
    	friend bool operator < (FrequentWord a, FrequentWord b)	//重载结构体小于号
    	{
    		if (a.weight == b.weight)	//权重小的排在队头,权重相同时,字典序大的排在队头
    			return a.word<b.word;
    		else
    			return a.weight > b.weight;
    	}
    }fqtWord;
    priority_queue<FrequentWord> q_Word;	//创建一个优先队列,用来保存词频高的单词
    
    
    
    void triePreorderTraversal(trie root, int maxNumber)	//树的先序遍历
    {
    	if (root == NULL)
    		return;
    	if (root->weight != 0)
    	{
    		fqtWord.weight = root->weight;
    		fqtWord.word = root->word;
    
    		if (q_Word.size()<maxNumber)	//维护maxNumber大小的优先队列
    		{
    			q_Word.push(fqtWord);
    		}
    		else
    		{
    			q_Word.push(fqtWord);		//push一个新的结构体,队列会将权重小或字典序小的结构体排在队头
    			q_Word.pop();				//移出队列
    		}
    	}
    	for (int i = 0; i<ALPHABET_SIZE; i++)
    	{
    		triePreorderTraversal(root->children[i],maxNumber);
    	}
    }
    
    
    
    
    void FrequentWordCount(int maxNumber)
    {
    	triePreorderTraversal(root_Words,maxNumber);
    
    	while (!q_Word.empty())		//保存优先队列内容,将数组倒序输出,即是所求词频
    	{
    		fqtWord = q_Word.top();
    		str_Words[d] = fqtWord.word;
    		ans_Words[d] = fqtWord.weight;
    		d++;
    		q_Word.pop();
    	}
    	//return root;
    }
    

    性能分析与改进

    1.改进的思路

    原先在判定n个单词是不是词组时,采用的是一次性抓取n个单词,如果这n个都是合法单词,则找到一个词组,否则前进一步,继续抓取n个单词,然后发现这样会造成重复判断同一个单词多次,效率低下,因而改进了算法,维护一个n+n-1的队列(n为词组长度),按顺序检索文本,遇到合法单词,压入该单词和单词后的分隔符串,如果队列未满,则什么都不干,如果队列恰好满了,则找到一个词组,此时将队头的合法单词和分隔符串移出队列。遇到非法单词,则直接清空队列。这样保证每个单词至多只会判断一次,提高了效率。

    2.展示性能分析图和程序中消耗最大的函数

    如图所示。


    单元测试

    对于WordCount给出如下10个单元测试,思路是尽可能为难编码者以更容易找到bug,其中Test1-Test7针对字符总数、单词总数、有效行数、部分异常进行测试,Test8、Test9针对单词词频进行测试,Test10针对词组词频进行测试。

    测试序号 测试简介
    Test1 无合法单词测试
    Test2 空文件测试
    Test3 特殊符号测试
    Test4 合法单词判断测试
    Test5 文件不存在测试
    Test6 多个有效行测试
    Test7 较长的合法单词测试
    Test8 大小写相同测试
    Test9 单词词频结果测试
    Test10 词组词频结果测试

    部分代码如图:


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

    爬虫方面:爬虫工具无法直接输出符合要求格式的txt,有点崩溃,一开始考虑使用某算法对txt进行排版,不过感觉有点复杂,后来选择先导出为excel,可以在excel上很方便地加入序号0到978,并在结尾加入无关紧要的后缀(比如“两个空行”),然后复制到word,把“两个空行”都替换为两个回车,如此便解决了空行问题。当然还有一些小的排版问题,不过都是可以用word容易解决的,在此不多赘述。即利用了excel和word的优势对采集的数据进行了处理。
    代码方面:当遇到输入异常或文件异常时,继续运行会出错,因此选择输出相应的异常:





    附加题设计与展示

    在result.txt的基础上,额外爬取了作者和PDF链接。如下图所示:


    评价你的队友

    1.值得学习的地方

    我的队友超强的,算法思路清晰明确,编码能力极佳,这些都是我所欠缺的。

    2.需要改进的地方

    太懒了,每次都在deadline前一刻才出炉完整代码。


    学习进度条

    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    3 0 0 17 17 Axure Rp;NABCD模型
    4 1000 1000 23 40 八爪鱼采集器;字符统计
  • 相关阅读:
    Linux磁盘分区、格式化和挂载
    通过Fiddler监控Java应用发送请求及相应数据
    使用Apache Commons IO组件读取大文件
    export default 和 export 的使用方式
    vue+webpack4 脚手架搭建
    async/await中reject的问题
    NodeJS 开发博客(五) 使用express脚手架
    常考JS题笔记
    让你弄懂 call、apply、bind的应用和区别
    JS闭包解析
  • 原文地址:https://www.cnblogs.com/Huangpx/p/9769822.html
Copyright © 2020-2023  润新知