詞頻統計 (個人項目)
要求
(1). 實現一個控制台程序,給定一段英文字符串,統計其中各個英文單詞(4字符以上含4字符)的出現頻率。 附加要求:讀入一段文本文件,統計該文本文件中單詞的頻率。
(2). 性能分析:
- 對C++代碼運行VS的性能分析工具,找出性能問題並進行優化。
- 對Java程序運行性能分析工具 NetBeans IDE 6.0,找出性能問題並進行優化。
開發語言:C++
各個模塊時間(預估/實際)(本來預估3-4h可完成,但實際花了將近6-7h)
預估時間 | 實際時間 | |
詞頻統計 | 1.5h | 1.5h |
大小寫轉換 | 0.75h | 1h |
長度小於4的單詞刪除 | 0.75h | 1.5h |
多個分隔符區分 | 1h | 2h |
由於上一次老師提過代碼的規范性,所以這一次的代碼我特意注意了代碼的書寫規范。
下面是源代碼:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 struct Word /* 單詞對象 */ 6 { 7 Word() : Str( "" ), Count( 0 ) 8 { 9 } 10 string Str; 11 int Count; 12 }; 13 14 15 void CalcCount( Word *words, string &content, int size ) /* 統計詞頻 */ 16 { 17 int i; /* words單詞 content內容 size個數 */ 18 for ( i = 0; i < size; i++ ) 19 { 20 if ( words[i].Str == content ) 21 { 22 words[i].Count++; 23 return; 24 }else if ( words[i].Str == "" ) 25 break; 26 } 27 words[i].Str = content; 28 words[i].Count = 1; 29 } 30 31 32 int main() 33 { 34 char ch; 35 Word *words; 36 string content; 37 cout << "輸入一段英文:"; 38 getline( cin, content ); 39 while ( cin.get( ch ) ) /* 把所有小寫字母換成大寫字母 */ 40 { 41 ch = cin.get(); /* 此部分存疑,可能是輸入問題,這一部分無法實現 */ 42 if ( 97 <= ch && ch <= 122 ) 43 { 44 char (ch) = char(ch - 32); 45 break; 46 } 47 } 48 49 int wCount = 1; /* 計算單詞總數 */ 50 if ( content.length() < 4 ) /* 長度小於4的單詞刪除 */ 51 { 52 wCount--; 53 content.erase( 0, offset + 1 ); 54 offset = content.find( ' ' ); 55 continue; 56 } 57 for ( unsigned int i = 0; i < content.length(); i++ ) 58 { 59 if ( content[i] == ' ' || content[i] == '\t' || content[i] == '\n' || content[i] == '.' || content[i] == ',' ) 60 wCount++; /* 分隔符分為' ','\t','\n',',','.'五種 */ 61 } 62 words = new Word[wCount]; 63 64 string::size_type offset = content.find( ' ' || '\t' || '\n' || '.' || ',' ); /* 單詞以分隔符隔開 */ 65 while ( offset != string::npos ) 66 { 67 string wStr = content.substr( 0, offset ); 68 content.erase( 0, offset + 1 ); 69 CalcCount( words, wStr, wCount ); 70 offset = content.find( ' ' || '\t' || '\n' || '.' || ',' ); 71 } 72 CalcCount( words, content, wCount ); 73 74 for ( int j = 0; j < wCount; j++ ) /* 最后輸出結果 */ 75 { 76 cout << words[j].Str << ":" << words[j].Count << endl; 77 } 78 delete[] words; 79 return(0); 80 }
運行結果(老師給的例子):
我的分析:
由上圖可以看出,結果並不完全正確,我的代碼里面,小寫字母全部轉換成大寫字母那一塊出了問題。我前前后后大概改了十幾次,也翻閱了C++書,我覺得可能是輸入讀取出了問題,但是怎么改都無濟於事,這個問題算是存疑,之后我會借助同學或者老師的力量解決這個問題的。
我的總結:
由於JAVA的初步學習我覺得還不夠讓我寫出這樣一個程序,所以我還是選擇了C++語言寫了這個程序。這次源代碼,我花的時間比預計的時間多了很多,一部分原因是C++知識的疏漏和遺忘,另一部分原因就是題目的要求細節的難度比較高。這個詞頻統計的題目,雖然以前做過字母的統計,大小寫轉換,分隔符區分等等程序,但是要寫出這個充滿細節需要的程序,確實難上加難,甚至我最后還存了疑,在小寫字母全部轉換成大小字母這兒問題上,並沒有完全解決,短時間內可能再卡在這里,所以我選擇之后借助一個同學和老師的力量解決。
github鏈接:https://github.com/liuyutianlyt/CalcCount.md