C++讀取文件統計單詞個數及頻率


1.Github鏈接

GitHub鏈接地址https://github.com/Zzwenm/PersonProject-C2

2.PSP表格

PSP2.1 Personal Software Process Stages 預估耗時(分鍾) 實際耗時(分鍾)
Planning 計划
• Estimate • 估計這個任務需要多少時間 480 720
Development 開發
• Analysis • 需求分析 (包括學習新技術) 120 180
• Design Spec • 生成設計文檔 30 40
• Design Review • 設計復審 40 60
• Coding Standard • 代碼規范 (為目前的開發制定合適的規范) 30 20
• Design • 具體設計 40 60
• Coding • 具體編碼 150 180
• Code Review • 代碼復審 120 180
• Test • 測試(自我測試,修改代碼,提交修改) 60 90
Reporting 報告
• Test Repor • 測試報告 60 40
• Size Measurement • 計算工作量 20 30
• Postmortem & Process Improvement Plan • 事后總結, 並提出過程改進計划 30 30
合計 700 910

3.計算模塊接口的設計與實現過程

/*定義words用於記錄單詞數量*/
typedef struct {
	string word;
	int num;
}words;
/*定義一個容量用於存單詞,方便后續的單詞排序*/
vector<words> v;
/*定義類File記錄.txt文件的信息*/
class File {
private:
	int character;  //字符數
	int word;  //單詞數
	string filename;  //文件名
public:
	File();
	File(string s);  //通過命令行傳參獲取filename
	void get_character();
	void get_word();
	void get_mostword();
	void get_all();
};
/*分別統計字符數、統計單詞數和統計最多的10個單詞及其詞頻*/

程序通過命令行傳參獲取.txt文件記錄到filename中便於成員函數使用讀取文件。在調用成員函數統計時直接將字符數、單詞數記錄到file中,單詞及單詞出現個數記錄到words中並存入容量v中。
基本功能:
1.統計字符數
直接讀取文件每個字符記錄即可

	file >> noskipws;// 記錄所有字符 
	file >> temp;
	while (!file.eof())
	{
		character++;
		file >> temp;
	}

2.統計單詞數
由於單詞有規定:至少以4個英文字母開頭,跟上字母數字符號,單詞以分隔符分割,不區分大小寫。
所以需要對文件內容進行篩選,將每個字符連接起來記錄到string s中char a[2] = { temp,0 };s += temp;,在每遇到一個分隔符進行一次篩選。判斷單詞長度是否超過三,且前四個字符要都為英文字母,符合條件則到容量v中查找是否有相同單詞並記錄次數。一直讀取到文件末尾即可。
3.統計文件的有效行數:任何包含非空白字符的行,都需要統計。
設立一個變量用於統計每行非空白字符是否為零即可,非零即為有效行數。
4.統計文件中各單詞的出現次數,最終只輸出頻率最高的10個。頻率相同的單詞,優先輸出字典序靠前的單詞。
在統計單詞數時已經存到了容量v中,進行一次排序即可。可以利用sort函數對單詞進行排序。
sort(v.begin(), v.end(), set_word);set_word為bool函數用於比較順序
bool set_word(const words &a, const words &b) { if (a.num == b.num)return a.word<b.word;else return a.num>b.num; }

4.計算模塊接口部分的性能改進

由於第一步實現基本功能時沒有對基本功能進行分離,全部寫在了同一部分中,所以需要從中分離出,刪除掉沒用的部分。字符統計可以直接提取出來寫成一個函數,統計單詞時只需要將字符統計部分刪除掉結合class file統計即可。

5.計算模塊部分單元測試展示。

TEST_METHOD(TestMethod1)
{
	// TODO: 在此輸入測試代碼
	myFile file("in.txt");
	Assert::AreEqual(745,file.get_characters());

}
TEST_METHOD(TestMethod2)
{
	// TODO: 在此輸入測試代碼
	myFile file("in.txt");

	Assert::AreEqual(72, file.get_words());
}
TEST_METHOD(TestMethod3)
{
	// TODO: 在此輸入測試代碼
	myFile file("in.txt");

	Assert::AreEqual(11, file.get_lines());
}

測試出現問題失敗了

經過多次測試發現將pch.cpp中的函數寫在pch.h中就不會有報錯。
上網查閱資料后發現在測試的cpp中加入

#include"../wordCount/pch.h"
#include"../wordCount/pch.cpp"

就可以解決問題。

Assert::AreEqual(2230243,file.get_characters());// 測字符數
Assert::AreEqual(232213, file.get_words());//測單詞數
Assert::AreEqual(15744, file.get_lines());//測有效行數

測試

計算模塊部分異常處理說明。

ifstream file(filename);
//添加錯誤提示說明 在讀取文件失敗時提示
if (!file)
{
	cerr << "open error!" << endl;
	exit(1);
}

感想

這次的代碼及封裝很早就完成實現了,大部分內容都需要在網上查閱資料學習,讀取文件,輸出文件,讀取文件中的字符,單詞的字典排序都需要上網學習一下,不過內容比較簡單,很快就完成了。在封裝的時候,由於個人的習慣,一直以來都沒有面向對象的習慣,所以都將代碼寫在了main()函數中,所以在分離封裝時又耗費了很久。同時也讓我學會在編程時要學會封裝接口,方便簡潔。在弄單元測試時,新建測試時弄了預編譯頭,出現了意外的錯誤,上網查找了解決辦法,修改了設置,弄得連最基本的調試都不能完成了。在修復后重新編寫單元測試還是遇到這個問題,沒有完成單元測試。在后續經過多次測試,終於找到了解決方法,也算是收獲了單元測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM