1.结对同学的博客链接、本作业博客的链接、所Fork的同名仓库的Github项目地址

Github地址:https://github.com/Stellaaa18/pair-project

结对同学的博客链接:http://www.cnblogs.com/Stella12/p/9769114.html

本作业博客的链接:https://edu.cnblogs.com/campus/fzu/Grade2016SE/homework/2138

2.分工

  杨礼亮:负责爬虫、处理数据;分权重词频统计部分代码;实现字符、行数统计部分代码;

  (队友)林翔宇:负责实现多参数混合使用功能实现;词组、单词、统计部分代码;负责整合代码;性能分析;

  各自写自己负责部分的博客。

3.PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

20

30

· Estimate

· 估计这个任务需要多少时间

20

30

Development

开发

750 820

· Analysis

· 需求分析 (包括学习新技术)

200

230

· Design Spec

· 生成设计文档

30

40

· Design Review

· 设计复审

30

10

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

100

60

· Design

· 具体设计

200

 300

· Coding

· 具体编码

100

100

· Code Review

· 代码复审

30

20

· Test

· 测试(自我测试,修改代码,提交修改)

60

60

Reporting

报告

80

 100

· Test Repor

· 测试报告

60

 60

· Size Measurement

· 计算工作量

5

 5

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

15

 35
 

合计

850

 950

4. 使用工具爬取论文信息

爬虫工具:八爪鱼采集器

使用方法:

  这个工具使用起来很简易。

  首先建立一个自定义采集,输入将要采集的网页网址,保存网址后便会自动跳转。

  第二,我将标题与简介分开采集,采集标题只需要在本页面直接采集,采集简介要设计循环链接。

  采集完成后就可以以excel格式导出,再将excel中的数据粘贴到文本中。

  我是将标题和简介放到两个文本中,采集后的数据比较混乱,需要按格式输出,所以用c语言写了一些程序来整理文本。

这里附上一些伪代码

//在简介前面加上 Abstract:
void Abstract(char *filename)
{ifstream file;file.open(filename);string s;string t="Abstract: ";ofstream fileOutput;fileOutput.open("2.txt", ios::app);while(getline(file, s)){fileOutput << t+s << endl;}file.close();
}

//在标题前面加上 Title:
void Title(char *filename)
{ifstream file;file.open(filename);string s;string t="Title: ";ofstream fileOutput;fileOutput.open("1.txt", ios::app);while(getline(file, s)){fileOutput << t+s << endl;}file.close();
}

//按格式输出
void Title(char *filename)
{ifstream file;file.open(filename);string s;int count= 979;for(int i=0;i<count;i++){getline(file, s);title[i]=s;}file.close();
}void Abstract(char *filename)
{ifstream file;file.open(filename);string s;int count= 979;for(int i=0;i<count;i++){getline(file, s);abstract[i]=s;}file.close();
}int main()
{ofstream fileOutput;fileOutput.open("result.txt", ios::app);char filename1[105]= "1.txt";char filename2[105]= "2.txt";Title(filename1);Abstract(filename2);int count= 979;for(int i=0;i<count;i++){ fileOutput<<i<<endl;fileOutput<<title[i]<<endl;fileOutput<<abstract[i]<<endl;fileOutput<<endl<<endl;}return 0;
}

  最终结果如下

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

分装成五个接口函数,分别实现多参数混合使用、字符统计、行数统计、词组统计、分权重词频统计

int AnalyseParameter(char **argv);
int CountChar(string name);
int CountLines(string name);
void PhraseFreq(string str);
void TopNPhrases();
int WordFreq(string s);
void TopNWords();

内部实现如下:

类图:

6.算法的关键与关键实现部分流程图

本次任务的关键在于词组统计的实现,实现部分代码如下:

void PhraseFreq(string s)
{string word = "";string phrase = "";int cnt = 0, secWord;int len = s.length();for (int i = 0; i < len; i++) {if (s[i] >= 'A' && s[i] <= 'Z') {s[i] += 32; //change into lower case
        }if ((s[i] >= '0'&&s[i] <= '9') || (s[i] >= 'a'&&s[i] <= 'z')) {word += s[i];if (i == len - 1 && IsWord(word)) {cnt++;if (cnt == 1) {phrase += word;}else {phrase += " ";phrase += word;}if (cnt == 2) {secWord = i - word.size() - 1;}if (cnt == phraseLen) {if (weightOnWord && inTitle) {mapPhrase[phrase] += 10;}elsemapPhrase[phrase]++;i = secWord;}}}else if (word != "") {if (IsWord(word)) {cnt++;if (cnt == 1) {phrase += word;}else {phrase += " ";phrase += word;}if (cnt == 2) {secWord = i - word.size() - 1;}if (cnt == phraseLen) {if (weightOnWord && inTitle) {mapPhrase[phrase] += 10;}elsemapPhrase[phrase]++;i = secWord;cnt = 0;phrase = "";}}else {cnt = 0;phrase = "";}word = "";}}
}

流程图:

7.关键代码解释

以下是主函数的部分代码,用来处理输入文件

int main()
{ifstream fin(inputFile); string str;while (getline(fin, str)) { //按行读取文件内容 inTitle = 0;if (str.substr(0, 7) == "Title: ") {//"Title: "不计算在内str = str.substr(7, str.length());inTitle = 1;}else if (str.substr(0, 10) == "Abstract: ") {//"Abstract: "不计算在内str = str.substr(10, str.length());}else if (IsNum(str[0]) || str==""){ //不统计论文编号和空行continue;}if (countPhrase) {//countPhrase=1,启用词组词频统计
            PhraseFreq(str);}characters += CountChar(str);words += WordFreq(str);lines += CountLines(str);}fin.close();return 0;}
```
//统计一行中的词组词频
```
void PhraseFreq(string s)
{string word = "";string phrase = "";int cnt = 0, secWord;int len = s.length();for (int i = 0; i < len; i++) {if (s[i] >= 'A' && s[i] <= 'Z') {s[i] += 32; //大写转小写
        }//遍历到最后一个字符,和遇到分隔符一样,要判断当前词组是否符合条件if ((s[i] >= '0'&&s[i] <= '9') || (s[i] >= 'a'&&s[i] <= 'z')) {word += s[i];if (i == len - 1 && IsWord(word)) { cnt++;if (cnt == 1) {phrase += word;}else {phrase += " ";phrase += word;}if (cnt == 2) {secWord = i - word.size()-1;}if (cnt == phraseLen) {if (weightOnWord && inTitle) {mapPhrase[phrase] += 10;}elsemapPhrase[phrase]++;i = secWord;}}}else if(word!=""){ //遇到分隔符且word不为空if (IsWord(word)) { //如果是有效单词cnt++;//单词加到phrase中if (cnt == 1) {phrase += word;}else {phrase += " ";phrase += word;}if (cnt == 2) { //记录词组第二个单词的位置secWord = i - word.size()-1;}if (cnt == phraseLen) { if (weightOnWord && inTitle) { //若启用权重统计并且是属于title的单词mapPhrase[phrase]+=10; //权重为10
                    }elsemapPhrase[phrase]++;i = secWord; //回到第二个单词首cnt = 0;  //当前单词数清零phrase = ""; //phrase清零
                }}else {cnt = 0;phrase = "";}word = "";}}
}

8.性能分析与改进

展示性能分析图和程序中消耗最大的函数
使用爬取的论文进行测试,输入命令行参数为WordCount.exe -i paper.txt -o result.txt -w 1 -m 3 -n 10,运行时间为18.716s,输出结果如下:

性能报告截图:

从中可以看出,消耗最大的函数是TopNPhrase(),占据总运行时间的49.1%。

9.单元测试

附上检测代码:

        TEST_METHOD(TestMethod1){string name;name="chartest1.txt";int chars = CountChar(name);Assert::AreEqual(chars, 40);}TEST_METHOD(TestMethod2){string name;name = "chartest2.txt";int chars = CountChar(name);Assert::AreEqual(chars, 74);}TEST_METHOD(TestMethod3){string name;name = "wordtest1.txt";ifstream fin(name);int words = 0;string str;while (getline(fin, str)) {inTitle = 0;if (str.substr(0, 7) == "Title: ") {str = str.substr(7, str.length());inTitle = 1;}else if (str.substr(0, 10) == "Abstract: ") {str = str.substr(10, str.length());}else if (IsNum(str[0]) || str == "") { //ignore paper number and empty linescontinue;}if (countPhrase) {PhraseFreq(str);}words += WordFreq(str);}fin.close();Assert::AreEqual(words, 5);}TEST_METHOD(TestMethod4){string name;name = "wordtest2.txt";ifstream fin(name);int words = 0;string str;while (getline(fin, str)) {inTitle = 0;if (str.substr(0, 7) == "Title: ") {str = str.substr(7, str.length());inTitle = 1;}else if (str.substr(0, 10) == "Abstract: ") {str = str.substr(10, str.length());}else if (IsNum(str[0]) || str == "") { //ignore paper number and empty linescontinue;}if (countPhrase) {PhraseFreq(str);}words += WordFreq(str);}fin.close();Assert::AreEqual(words, 9);}TEST_METHOD(TestMethod5){string name;name = "linetest1.txt";ifstream fin(name);int lines = 0;string str;while (getline(fin, str)) {inTitle = 0;if (str.substr(0, 7) == "Title: ") {str = str.substr(7, str.length());inTitle = 1;}else if (str.substr(0, 10) == "Abstract: ") {str = str.substr(10, str.length());}else if (IsNum(str[0]) || str == "") { //ignore paper number and empty linescontinue;}if (countPhrase) {PhraseFreq(str);}lines += CountLines(str);}fin.close();Assert::AreEqual(lines, 5);}TEST_METHOD(TestMethod6){string name;name = "linetest2.txt";ifstream fin(name);int lines = 0;string str;while (getline(fin, str)) {inTitle = 0;if (str.substr(0, 7) == "Title: ") {str = str.substr(7, str.length());inTitle = 1;}else if (str.substr(0, 10) == "Abstract: ") {str = str.substr(10, str.length());}else if (IsNum(str[0]) || str == "") { //ignore paper number and empty linescontinue;}if (countPhrase) {PhraseFreq(str);}lines += CountLines(str);}fin.close();Assert::AreEqual(lines, 5);}TEST_METHOD(TestMethod7){string name;name = "characterstest.txt";ifstream fin(name);int characters = 0;string str;while (getline(fin, str)) {inTitle = 0;if (str.substr(0, 7) == "Title: ") {str = str.substr(7, str.length());inTitle = 1;}else if (str.substr(0, 10) == "Abstract: ") {str = str.substr(10, str.length());}else if (IsNum(str[0]) || str == "") { //ignore paper number and empty linescontinue;}if (countPhrase) {PhraseFreq(str);}characters += CountChar(str);}fin.close();Assert::AreEqual(characters, 5);}TEST_METHOD(TestMethod8){string name;name = "phrasetest1.txt";ifstream fin(name);string str;while (getline(fin, str)) {inTitle = 0;if (countPhrase) {PhraseFreq(str);}}fin.close();if (countPhrase) { //phrase statistics
                TopNPhrases();}else { //word statistics
                TopNWords();}for (auto x : mapPhrase) {vecPhrase.push_back(x);}sort(vecPhrase.begin(), vecPhrase.end(), cmp2);Assert::AreEqual(vecPhrase[1].first, string("monday tuesday wednesday"));Assert::AreEqual(vecPhrase[1].second, 11);}TEST_METHOD(TestMethod9){string name;name = "phrasetest2.txt";ifstream fin(name);string str;while (getline(fin, str)) {inTitle = 0;if (countPhrase) {PhraseFreq(str);}}fin.close();if (countPhrase) { //phrase statistics
                TopNPhrases();}else { //word statistics
                TopNWords();}for (auto x : mapPhrase) {vecPhrase.push_back(x);}sort(vecPhrase.begin(), vecPhrase.end(), cmp2);Assert::AreEqual(vecPhrase[1].first, string("convolutional neural networks"));Assert::AreEqual(vecPhrase[1].second, 196);}

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

困难:

  尝试用python写爬虫;

  在结对合作的过程中,各部分的代码是两个人分开写的,在定义函数接口上出现的参数不一致的情况,合并代码麻烦;

  在写代码的过程中两个人都没有注释代码的习惯,看对方的代码特别吃力,很多变量和代码逻辑意思不懂。

  结对过程中联系很少,经常不知道对方的进度。

解决方法:

  用python写爬虫还没实现;

  彼此约定下次写各自代码时一定要注释清楚。

11.评价你的队友

  值得学习:办事效率高,代码能力强大,技术稳稳的,全程带飞我,紧抱队友大腿。

  需要改进的地方:合作过程沟通较少,彼此工作比较分离。

12.学习进度条

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
5 200 600 30 80

1.熟悉了爬虫工具的使用

2.使用c++处理数据

3.写代码过程中学会了新的算法

4.提高了分工合作能力

13.贴出Github的代码签入记录

转载于:https://www.cnblogs.com/YangLiLiang/p/9752105.html

福大软工1816 · 第五次作业 - 结对作业2相关推荐

  1. 福大软工1816:选题报告(团队作业二)

    "Jarvis For Chat"团队选题报告 组长博客链接 本次作业链接 NABCD在项目中的使用 N(Need,需求) QQ和微信已经成为人们社交的必需品,在QQ有7.8亿活跃 ...

  2. 福大软工1816 · 第一次作业 - 准备

    福大软工1816 · 第一次作业 - 准备 期待→迷茫→恐惧→振作or放弃? 前言:个人情况概述 虽然长辈都说我是个聪明的孩子,但我觉得也许那只是客套话-- 还记得从小学时我的成绩仅处于中游偏下,初中 ...

  3. 福大软工1816:项目测评

    福大软工 · 第十次作业 - 项目测评(团队) 评测 个人上手体验 查看课程表上效仿了超级课程表,界面美观 功能多,整合了课程表.查成绩.考场查询.历年卷.易班.空教室.图书馆.教务通知.大物实验.嘉 ...

  4. 福大软工1816:Alpha事后诸葛

    福大软工·第十一次作业-Alpha事后诸葛亮 组长博客链接 本次作业博客链接 项目Postmortem 模板 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描 ...

  5. 福大软工1816 · 第三次作业 - 结对项目1

    软工实践第三次作业-结对项目1 简要目录: Step1 · 结对信息     成员信息     项目简介 Step2 · 项目信息     设计说明     原型模型 Step3 · 结对过程     ...

  6. 福大软工1816 · 第一次作业——准备

    一.自我介绍 031602442:我是时而懒时而又异常坚持的郑孔宇:我的爱好是听音乐和玩游戏:我比较喜欢玫瑰一楼的拌面扁肉:及时行乐! 二.阅读与思考 1.回想一下你初入大学时对计算机专业的畅想 (1 ...

  7. 福大软工1816 · 第一次团队作业

    如果记忆是一个罐头的话,我希望这一罐罐头不会过期――――<重庆森林> 404 Note Found Team 如果记忆是一个备忘录的话,别说了,它不会过期――――<404 Note ...

  8. 福大软工1816:Alpha(3/10)

    Alpha 冲刺 (3/10) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.学习qqbot库: 2.实 ...

  9. 福大软工1816 - 404 Note Found选题报告

    目录 NABCD分析引用 N(Need,需求): A(Approach,做法): B(Benefit,好处): C(Competitors,竞争): D(Delivery,交付): 初期 中期 个人贡 ...

最新文章

  1. linux平台软件动态分析工具valgrind系列工具及其可视化
  2. 特权级——保护模式的特权级检查 DPL,RPL,CPL, 一致代码段,非一致代码段
  3. 关于Hadoop多用户管理支持客户端远程操作的理论总结
  4. gevent-tutorial翻译和解读
  5. Android之Activity框架
  6. 学法减分助手PRO小程序
  7. SpringBoot精通系列-使用Mybatis Generator生成Dao层代码
  8. Chrome 无法抓取跳转请求的解决办法
  9. java.sql.SQLException
  10. Zerodium 称 iOS exploit 过剩,将暂停收购且买价或下跌
  11. HDU2566 统计硬币【暴力】
  12. 类名作为形式参数传递
  13. 北理工计算机学院新闻,新闻睇睇睇 | 计算机学院举办第八届ACM/ICPC程序设计竞赛校内选拔赛暨北理工邀请赛...
  14. 杭州最新公交线路一览(91-100)
  15. VUE项目中高德地图选择坐标和输入搜索功能
  16. 欧盟CE公告号-外贸人不得不了解的通关证书
  17. 软考--快速掌握操作系统的PV操作
  18. 6000字总结MySQL最基础的增删查改命令
  19. 手机直播连麦技术分析
  20. 智能驾驶之技术概念综述

热门文章

  1. 使用Python获取DNS记录
  2. 摆渡人 --如果命运是一条孤独的河流,谁会是你的灵魂摆渡人
  3. DirectPlay分组功能 (转)
  4. 随机四位数的猜数游戏
  5. java串口rxtx下载_WINDOWS环境下JAVA串口RXTX编程DEMO
  6. 苹果手机上音乐播放的问题
  7. 基于A*搜索和深度优先搜索解迷宫问题
  8. 全球最专业的技术媒体,如何复盘 2019 AI 的发展?
  9. Altium Designer --> 电气电路
  10. c编程----段定义的使用