词频统计 (个人项目)
要求
(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] == ' ' || content[i] == ' ' || content[i] == '.' || content[i] == ',' ) 60 wCount++; /* 分隔符分为' ',' ',' ',',','.'五种 */ 61 } 62 words = new Word[wCount]; 63 64 string::size_type offset = content.find( ' ' || ' ' || ' ' || '.' || ',' ); /* 单词以分隔符隔开 */ 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( ' ' || ' ' || ' ' || '.' || ',' ); 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++知识的疏漏和遗忘,另一部分原因就是题目的要求细节的难度比较高。这个词频统计的题目,虽然以前做过字母的统计,大小写转换,分隔符区分等等程序,但是要写出这个充满细节需要的程序,确实难上加难,甚至我最后还存了疑,在小写字母全部转换成大小字母这儿问题上,并没有完全解决,短时间内可能再卡在这里,所以我选择之后借助一个同学和老师的力量解决。