詞頻統計——項目總結報告
一、 實驗內容:
1. 對源文件(*.txt,*.cpp,*.h,*.cs,*.html,*.js,*.java,*.py,*.php等,文件夾內的所有文件)統計字符數、單詞數、行數、詞頻,統計結果以指定格式輸出到默認文件中,以及其他擴展功能,並能夠快速地處理多個文件。
2. 使用性能測試工具進行分析,找到性能的瓶頸並改進
3. 對代碼進行質量分析,消除所有警告
4. 設計10個測試樣例用於測試,確保程序正常運行(例如:空文件,只包含一個詞的文件,只有一行的文件,典型文件等等)
5. 使用Github進行代碼管理
6. 撰寫博客
二、 需求分析:
按功能模塊分析:
- 遍歷目錄下所有文件。
- 文本模式讀寫文件。
- 統計文件總字符數。
- 統計文件總行數。
- 統計文件總單詞數。
- 統計文件中出現所有單詞及其個數。
- 統計文件中出現所有詞組及其個數。
- 找出單詞、詞組中出現頻率最高的十個元素。
- 按字典序輸出(統計單詞時不區分大小寫)。
- 移植Linux。
三、 設計方案:
按功能模塊設計:
- 1. 文件夾遍歷
使用WIN32_FIND_DATA、FILETIME結構體,遞歸遍歷目錄下所有文件。
詳情請見:http://www.cnblogs.com/collectionne/p/6792301.html
- 2. 文本模式讀寫文件
讀取FILE,fopen,fgetc,fclose;輸出:ofstream,outfile。
- 3. 字符數
fgetc讀入字符,根據作業要求按aclii碼判斷符合char_number++。
- 4. 行數
fgetc讀入字符,若為換行符,line_number++;對於結尾沒有換行符直接EOF的加一。
- 5. 單詞數
fgetc讀入字符,buf用於存儲字符串,j用於統計字符串長度,flag用於記錄當前是否有字符串在存貯,m用於記錄字符串中前連續字母的長度——通過對j長度的buf截取前m個實現真正單詞的存儲與計數。
- 6. 單詞頻數
通過unordered_map存儲單詞大寫形式與出現頻數,即unordered_map<string, double> dic;實現快速查找,修改頻數。
- 7. 詞組頻數
int p判斷buff中是否有單詞存儲,若無,讀到單詞直接存入buff並加入空格,若有,單詞後插入buff,得到詞組存儲,再將該單詞直接存入buff並加入空格。通過unordered_map存儲詞組大寫形式與出現頻數,即unordered_map<string, double> phr;實現快速查找,修改頻數。
- 8. 排序
初始化一個含有兩個元素string和int的結構體,分配10個空間,遍歷map,對元素按num進行插入排序。
- 9. 字典輸出
通過unordered_map<string, string> diction存儲單詞大寫形式與檢測到與該單詞不區分大小寫相同的字典排序最優形式。通過排序得到的string在unordered_map<string, string> diction中搜索,得到字典排序最優形式,輸出。
10. Linux移植
文件遍歷使用Get_All_Files()將所有路徑存入vector中,遍歷路徑即可。
四、 測試樣例:
- 空目錄、空文件、只包含空文件的文件夾
正常輸出各項均為0的result。對非目錄文件提示輸入目錄文件結束進程。
- 對空文件、不含換行符的文件、結尾無換行符的文件
正確輸出行數。
- newsample
多次測試,result穩定,字符數500的誤差,百萬分之二點八;總行數100的誤差,十萬分之四點三;單詞數9500的誤差,萬分之五點七。Top ten 單詞與詞組完全正確。
五、 性能分析:
對項目進行性能分析:
占據大部分時間的是unordered_map的內部hash,無法優化。
getcharnum是核心函數,字符行數單詞詞組的判斷都在其中,邏輯已多次優化。
trans是將字符串轉換為大寫的函數,考慮到字符中小寫較多,故嘗試修改將字符串轉換為小寫的函數
通過trans與其他函數相對工作比較,稍有成效。
六、 PSP表格
任務內容 |
計劃時間 |
實際用時 |
計劃 |
20 |
5 |
估算各任務所需時間規劃工作步驟 |
20 |
5 |
開發 |
1280 |
1060 |
需求分析 |
10 |
20 |
模塊解決 |
10 |
10 |
技術算法調研 |
60 |
30 |
具體寫代碼 |
800 |
700 |
測試 |
200 |
150 |
優化 |
200 |
150 |
報告 |
150 |
180 |
總結報告 |
120 |
150 |
經驗總結 |
30 |
30 |
總計 |
1450 |
1245 |
七、 經驗總結
本次作業我受益良多
工程方面:
- 完成了PSP。
- 使用GitHub進行了項目版本管理。
- 設計用例完成了單元測試。
- 撰寫了博客完成了項目總結。
- VS性能探查器做了性能分析。
技術方面:
- 學習了win下遍歷文件目錄。
- 學習了unordered,map的使用。
- 加深了對string的理解、文件流讀入寫出以及C++類的理解。
- 學習了new和malloc對與結構體的區別。
- 學習了Linux移植和gdb調試代碼。
整體來說,對這次作業完成情況還算滿意。一開始技術調研一定要做好,代碼框架數據結構定好避免大改。多查GitHub、論壇,避免造輪子;與同學間多交流,避免閉門造車;合理規劃時間,調整作息,避免通宵。
詞頻統計——項目總結報告