結對第二次—文獻摘要熱詞統計及進階需求

做業格式


具體分工

許林瑜:代碼的基礎功能編寫(我一開始沒認真看用DEVC++寫的。。。和VS環境差的有點多) ,博客碼字
楊吉:負責代碼優化,在VS2017上分裝接口(填個人坑)
together:找邏輯錯誤,作單元測試git

PSP表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃
•EStimate • 估計這個任務須要多少時間 60 80
Development 開發
• Analysis • 需求分析 (包括學習新技術) 60 60
• Design Spec • 生成設計文檔 60 40
• Design Review • 設計複審 120 110
• Coding Standard • 代碼規範 (爲目前的開發制定合適的規範) 60 50
• Design • 具體設計 120 120
• Coding • 具體編碼 120 150
• Code Review • 代碼複審 60 120
• Test • 測試(自我測試,修改代碼,提交修改) 60 50
Reporting 報告
• Test Repor • 測試報告 40 50
• Size Measurement • 計算工做量 30 20
• Postmortem & Process Improvement Plan • 過後總結, 並提出過程改進計劃 60 50
合計 790 850

解題思路描述:

  • 基本需求 :在拿到題目以後最早考慮的就是如何進行數據存儲,再者纔是去考慮如何去實現邏輯功能。在考慮用Java仍是C++中選着了一下 ,最後仍是用C++的STL來存儲數據結構,相對而言能夠本身定義構造和排序,可使代碼的邏輯更爲簡潔。找資料的第一時間想的就是去CSDN上找是否是有相似的問題,再反覆看了不少相似的問題代碼後有了初步的構思想法。接着就是在網站上找了關於STL容器的資料,瞭解容器是怎麼存儲數據結構的,而且瞭解了STl容器的基礎函數。找到操做可能須要的幾個函數先記下來,這樣子在後續的過程當中,有現成的函數也不用再花大量的時間去完成已經有的功能了(不要造重複的輪子)。
  • 進階需求,首先就是網上了解了如今經常使用的爬蟲軟件,而後就選擇相對成熟的爬蟲軟件經過博客,視頻等手段去了解如何使用,由於很好功能比較強大的爬蟲軟件都是外國軟件,麼得中文版本,因此本身直接下載使用的話仍是有一點難度的。
  • 固然作做業以前還要認真的閱讀《構建之法》的相關內容,以及助教們提供的相關博客連接。

設計實現過程

  • 首先思考如何存儲數據結構,而後再考慮怎麼去實現邏輯功能。
  • 最後採用了採用了C++中STL容器來存儲結構數組,因此並無本身定義新的類來存儲。因此麼得類圖(固然可能我不知道怎麼畫)結構體定義以下:
typedef struct word       //定義結構體用於存儲單詞結構
          {
            char w[Word_Max];    //單詞
             int count;           //個數     
           };

單詞采用字符數組記錄,Word_Max爲預約義的單詞數最大長度,單詞出現頻率用整型count存儲。github

  • 接着就是考慮到如何實現詞頻統計的基礎功能和如何將不一樣的功能分裝太不一樣的函數之中。經過對網絡上已有的一些源碼的參考,初步來將功能分紅幾個不一樣的函數好比添加詞頻記錄,將統計結果寫入文件中,I判斷是否爲合法單詞等。參考了網上的一些代碼而後根據本身的實際需求完成了基礎需求的代碼部分。

改進思路

性能分析
數組

  • 經過CPU的佔用率看,在外部調用的本身編寫的幾個函數中sortWord()的CPU佔用率最高
    可能和用List容器的使用有關,改進思路應該就是更改數據結構,使用更加方便訪問和查詢的數據結構來存儲。這樣子就能夠減小遍歷循環的次數,減小CPU的佔用。
    還有就是此次因爲太遲纔開始完成做業,爬蟲部分沒有來的作,本身測試的數據也未必可以測出性格的優劣,因此本身有空的時候還會把這個當成一個小目標來完成一下。

代碼說明

對list鏈表排序網絡

void sortWord(list<words> &a) {//對單詞出現次數排序

          a.sort([](words x, words y) {    重寫list中的sort()函數

          if (x.times != y.times)
                return x.times > y.times;

          else {

                if (x.s[0] > 90 && y.s[0] < 91)
                return (x.s[0] - 32) < y.s[0];
                else if (x.s[0] < 91 && y.s[0] > 91)
                return x.s[0] < (y.s[0] - 32);

          else

                return x.s[0] < y.s[0];

                  }
              });
            }

判斷單詞是否合法數據結構

int isRightWord(string s)//判斷是不是符合定義的單詞 

           {
                 if (s.size() < 4)    
                 return 0;   //單詞長度不知足return
                 int i; int x = 0;
                 for (i = 0; i < 4; i++)
                 {
                     if (s[i] <= 'z' && s[i] >= 'a')
                         x++;
                     else if (s[i] <= 'Z' && s[i] >= 'A')
                         x++;
                   }
                  if (x != 4 )   //用x統計單詞是否以四個字母開頭
                       return 0;
                   else
                       return 1;
           }

判斷字符的ASCII碼是否符合函數

int isLlegal(char a)  {       //判斷字符的ASCII碼是否符合

               if (a <= 'z' && a >= 'a')
              {
                       return 1;
              }
               else if (a <= 'Z' && a >= 'A')
               {
                       return 1;
               }
               else if ('0' <= a && a <= '9') {
                       return 1;
                }
               else
                      return 0;
                }

鏈表中插入單詞並計數工具

void addToList(list<words> &a, string s)
{
                 int i = 1;
                 for (auto &x : a) {
                 if (s == x.s)
                {
                       x.times++;
                       i = 0;
                       break;
                 }
              }
                 if (i == 1) {
                 a.push_back(words(s, 1));// 遍歷一遍,若是沒有出現重複單詞就在鏈表尾部插入
                }
           }

分割單詞(設置全局變量,每分割一次就COUNT++)性能

void IsWord(string s, list<words>&a)    //統計單詞
              {
                  int i = 0, j = 0;
                   string word;
                   for (int k = 0; k < s.size(); k++)
                   {
                         if (!isLlegal(s[k]))    //若是不知足單詞組成則分割單詞,判斷是否爲合法單詞是否要插入

                         {
                               if (isRightWord(word))
                             {
                                   addToList(a, word);
                             }
                              word = "";
                         }
                     else
                     {
                            word.push_back(s[k]);     未完成分割單詞則把字符讀入字符串最尾                      
                     }
                    }
                  }

統計函數(主要是添加全局變量,在讀取文本是每getline()一次就COUNT++)單元測試

int countLines(string s) {
             ifstream pFile;
             string buffer;
             pFile.open(s); // 打開文件
             int count = 0;
             for (string temp; getline(pFile, temp);)     //將論文讀入字符串
             {
                      if (temp != "")
               {
                     buffer += temp;
                     count++;
               }
              }
              cout << "lines:" << count << endl;
              pFile.close();
              return count;
             }

單元測試

單元測試用的是Visual Studio 2017上自帶的C++單元測試功能
在原有的項目下新建UnitTest1項目,並將引用指向原來的項目
在unittest1.cpp中使用宏"TEST_METHOD"包裹方法將不一樣的函數分紅獨立的測試單元學習

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../core/core.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:

        TEST_METHOD(TestMethod1)

        {

            std::string textString = "asd31111";

            

            Assert::AreEqual(isRightWord(textString), 0);

        }

        TEST_METHOD(TestMethod2) {

            std::string textText = "a.txt";
            Assert::AreEqual(countLines(textText), 3)

        }

    };

}

使用了Assert中的Assert::AreEqual();來對輸入與輸出是否相等進行判斷。測試了ASCII和單詞判斷的函數。可是由於仍是第一次使用單元測試這種作法因此只是初步的測試了一下,更多的測試仍是用比較老土的那種方法。

測試的數據主要就是針對不一樣的函數進行測試,由局部基礎的邏輯函數進行測試,一步步測試到整個項目;
- 測試判斷ASCII碼的函數就是用不一樣的輸入 好比:A a @ # 空字符等去判斷返回值是否正確
- 判斷是不是合法的單詞事用不一樣的字符串進行測試 好比:12asjda , ada , hhhh(asdsad) ,asdajsdja2019 ,adadad;等對常見的字符輸入進行測試,觀測返回值是否正確。
- 判斷排序,字符串分割等函數是否正確,主要是去網上找了英文論文做爲輸入,而後觀測輸出數據與人爲數的數據是否有誤差,好比排序。是否按要求輸出,替換文中的單詞如win(10)次
adsada(10)次是否會正確排序。還測試了空文件,以及較大的文件。

Github的代碼簽入記錄

遇到的困難及解決辦法

  • 遇到的困難
    • 剛開始鬼使神差的用結構鏈表來存儲詞頻統計結果,以爲遍歷一遍只是簡簡單單的事情,而後一開始也寫的很正常。而後而後就是......不會排序,好吧我認可我指針學的不是很好。而後就要面臨怎麼排序的問題了。
    • 還有就是result的異常啊這些,好比詞頻統計的數量出錯,字符串訪問出錯,單詞漏讀等等
    • 最困難的就是老師要求的那些本身也沒有見過的東西,剛開始用起來真的是很頭疼。
  • 解決方法
    • 去學了一下List容器採用List鏈表來存儲(以前那個坑是我挖的。。)而後隊友就負責把原來的儲存結構修改了一下,而後重寫了List的排序函數就OK了
    • 第二個關於result 的問題無非就是函數邏輯上的問題,調試了一下就解決了呀。
    • 經過老師給的博客連接,和本身上網找資料,也是在慢慢摸索中學會了不少之前不會的技能和工具吧。

隊友評價

  • 隊友在這個學期剛開始就很認真的準備考研了。天天真的除了上課和晚上休息以外都在外面讀書,很認真很辛苦。可是在完成做業的這個禮拜裏仍是每一個晚上都回到宿舍來完成做業。不是不想作軟工,只是但願下次能夠把需求搞清楚,而後少一點花裏胡哨的時間。如今是大三下不是大三上來,但願你們均可以相互體諒,咱們仍是會按要求好好完成做業的 ,隊友在天天完成任務的這段時間都很認真的在作,比我認真。調試也很認真,反正就是很專心很認真的對待這個做業並不會由於要考研就把任務多分給我,跟他作隊友挺好的,好認真很負責,因此但願助教能夠給他多打一些分嘻嘻。
相關文章
相關標籤/搜索