軟工做業五

隊友連接:

http://www.cnblogs.com/waaaafool/p/9768456.htmlhtml

具體分工:

胡青元實現詞頻統計、代碼複審、性能分析、單元測試、改進前端

何宇恆實現爬蟲、博客編寫java

代碼規範:http://www.javashuo.com/article/p-wnampkgf-bw.htmlpython

PSP表格:

PSP Personal Software Process Stages 2 預估時間(分鐘) 實際耗時(分鐘)
Planning 計劃 20 35
Estimate · 估計這個任務須要多少時間 960 1400
Development 開發 180 280
· Analysis · 需求分析 (包括學習新技術) 100 100
· Design Spec · 生成設計文檔 30 30
· Design Review · 設計複審 60 60
· Coding Standard · 代碼規範 (爲目前的開發制定合適的規範) 0 0
· Design · 具體設計 300 500
· Coding · 具體編碼 200 240
· Code Review · 代碼複審 50 30
· Test · 測試(自我測試,修改代碼,提交修改) 30 45
Reporting 報告 30 30
· Test Repor · 測試報告 30 30
· Size Measurement · 計算工做量 20 20
· Postmortem & Process Improvement Plan · 過後總結, 並提出過程改進計劃 30 30
合計 1380 1440

解題思路描述與設計實現說明

爬蟲使用

最開始使用的是工具爬蟲。採用八爪魚採集器,簡略使用方法:git

登錄後點擊向導採起github

輸入網址:算法

選擇:編程

便可爬取網頁中的連接的內容數組

缺點:雖能夠較快完整爬取信息,但格式極難調整數據結構

後用python實現

import requests
from urllib.request import urlopen
from bs4 import BeautifulSoup
txt = open (r'C:\Users\胖若兩人\Desktop\result.txt' , 'w', encoding='utf-8' )//result文件地址
i=0
def getPaper (newsUrl) :
      res = requests. get (newsUrl)
      
      res. encoding = ' utf-8'

      soup =  BeautifulSoup (res. text, 'htm1. parser' )

      Title = soup. select( '#papertitle') [0]. text. strip()
      
      print("Title:", Title, file=txt)

      Abstract = soup. select( '#abstract' ) [0]. text. strip()
      
      print ( "Abstract:", Abstract,"\n\n" , file=txt)
      
      return

      sUr1 = 'http:// openaccess. thecvf. com/ CVPR2018. py'
      
      res1 = requests. get (sUrl)
     
      res1. encoding = 'utf-8'

      soup1 = BeautifulSoup (res1. text, 'htm1. parser' )
      
      for titles in soup1. select('. ptitle') :

          t ='http://openaccess thecvf. com/'+ titles. select( 'a' )[0][ 'href ']
          print(i, file=txt)
      
          getPaper (t)
      
          i=i+1

大體思路以下:

根據指定的url地址 去發送請求,得到響應, 而後解析響應 , 一方面從響應中查找出想要查找的數據,另外一方面從響應中解析出新的URL路徑,

而後繼續訪問,繼續解析;繼續查找須要的數據和繼續解析出新的URL路徑

image

代碼組織與內部實現設計

void charCount(const char* file, const char* file1);
//統計單詞個數

void frequency(int w_flag,int times, const char* file, const char* file1);
//統計單詞頻率,w_flag斷定是否啓用加權,times肯定輸出個數。

void lineCount(const char* file, const char* file1);
//統計行數

void p_frequency(int w_flag,int times, int m, const char* file, const char* file1);
//統計詞組頻率,w_flag斷定是否啓用加權,times肯定輸出個數,m是詞組的單詞組成數量

void wordCount(const char* file, const char* file1);
//統計單詞個數

說明算法的關鍵與關鍵實現部分流程圖

三、算法的關鍵是用NFA讀取單詞,進行斷定,若是是單詞就入隊,而後記錄此單詞與下一個單詞之間的分隔符,也入隊。若是隊列的大小大於等於2*m-1,就能夠進行讀出字符串記錄在hash_map裏,若遇到非法單詞,則清空隊列。流程圖以下:

關鍵代碼解釋

string s = "";
    unordered_map<string, int> wordList;
    queue<string>que;
    queue<string>que_temp;
    int num = 0;//狀態轉換標識 0,1,2,3,4
    int flag = 1;
    int more_flag = 0;
    while (1) {

        char c;
        if (!more_flag) {
            fin.get(c);
            if (fin.eof()) {
                break;
            }
        }
        else {
            more_flag = 0;
        }


        if ('A' <= c && c <= 'Z') c = c + 32;

        if (num == 0) {
            if ('a' <= c && c <= 'z') {
                s += c;
                num++;
            }
            else {
                while (!que.empty()) {
                    que.pop();
                }
            }
        }
        else if (num == 1) {
            if (('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) {
                s += c;
                num++;
            }
            else {
                num = 0;
                s = "";
                while (!que.empty()) {
                    que.pop();
                }
            }
        }
        else if (num == 2) {
            if (('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) {
                s += c;
                num++;
            }
            else {
                num = 0;
                s = "";
                while (!que.empty()) {
                    que.pop();
                }
            }
        }
        else if (num == 3) {
            if (('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) {
                s += c;
                num++;
            }
            else {
                num = 0;
                s = "";
                while (!que.empty()) {
                    que.pop();
                }
            }
        }
        else if (num == 4) {
            if (('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) {
                s += c;
                num = 4;
            }
            else {
                string s1 = s + c;
                if (s1 == "title:"&&w_flag==1) {
                    flag = 10;
                }
                else if (s1 == "abstract:"&&w_flag==1) {
                    flag = 1;
                }
                else {
                    que.push(s);
                    string s2;
                    s2 += c;
//讀分隔符
                    while (1) {
                        fin.get(c);
                        if (fin.eof()) {
                            break;
                        }
                        if ('A' <= c && c <= 'Z') c = c + 32;
                        if (!(('a' <= c && c <= 'z')||('0'<=c&&c<='9'))&&c>=32) {
                            s2 += c;
                        }
                        else {
                            que.push(s2);
                            more_flag = 1;
                            break;
                        }
                        
                    }
                }
//若是知足條件,就進行隊列訪問,獲取數組字符串
                if (que.size() >= (unsigned)(2 * m - 1)) {
                    que_temp = que;
                    string s3;
                    for (int i = 0; i < 2 * m - 1; i++) {
                        s3 += que_temp.front();
                        que_temp.pop();
                    }
                    wordList[s3] += flag;
                    if (que.size() >= 2) {
                        que.pop();
                        que.pop();
                    }
                }
                s = "";
                num = 0;
            }
        }
    }
//若是文件末尾不屬於分割符,須要補充
    if (num == 4) {
        string s3;
        if (que.size() >=(unsigned) (2 * m - 2)) {
            while (!que.empty()) {
                s3 += que.front();
                que.pop();
            }
            s3 += s;
            wordList[s3] += flag;
        }

}

流程圖

性能分析與改進

性能分析:讀取字符串時間複雜度爲o(n),hash_map的添加操做是o(n),查找爲o(1)。
性能改進:查詢時發現,map的組織形式是有序,而咱們的算法並不須要有序,因此換成了unordered_map。

展現性能分析圖和程序中消耗最大的函數

單元測試

單元測試:
由於IDE中出現了問題,沒有test,百度以及重裝了也沒辦法,因此只能手工測試。
下面是參考網上寫的簡單測試模板:

namespace UnitTest1 
{ TEST_CLASS(UnitTest1) 
{ public: TEST_METHOD(TestMethod1) 
{ char file[] = "E:\\222.txt"; int num = Tool::CharCount(file); Assert::IsTrue(num == 1);// TODO: 在此輸入測試代碼 } 
};

Github的代碼簽入記錄

Github:

https://github.com/hyh1998/pair-project

遇到的代碼模塊異常或結對困難及解決方法

寫代碼時設計好了算法,以及數據結構,可是在書寫過程當中犯了不少低級錯誤,好比(==寫成=),因此debug了好久也沒debug出來。
最後只能經過對代碼進行明確的規劃,以及從新寫一遍並注意編程細節來解決。

評價你的隊友

值得學習的地方

對代碼認真負責、準時完成任務,對待隊友耐心負責

須要改進的地方

對待隊友太寬容

學習進度條

第N周 新增代碼(行) 累計代碼(行) 本週學習耗時(小時) 累計學習耗時(小時) 重要成長
4 135 135 3 3 熟悉java語言基礎
5 350 485 5 8 初步創建前端
相關文章
相關標籤/搜索