首页 > 代码库 > 华为历年试题(单词统计3)
华为历年试题(单词统计3)
单词统计
题目描述:
输入一段英文文本,用程序统计出现频率最高和最低的两个单词;
英文文本中仅出现这四类字符:空格( )、英文逗号(,)、英文句号(.)、英文大小写字母(a-z、A-Z)
单词之间的分隔符仅考虑这三种:空格( )、英文逗号(,)、英文句号(.);
仅大小写不同的单词算同一个单词;
如果两个单词出现次数相同,则在文本中首次出现的单词优先返回。
返回的单词统一用小写字母返回
例如:
输入字符串“Hello world, i said hello world to the world”,返回“world”,“i”
输入字符串“Somebody like somebody,i do not like it”,返回“somebody”,“i”
要求实现函数:
void WordStat(const char * pInputStr, char * pOutputHotWord, char * pOutputColdWord);
【输入】 pInputStr: 输入字符串,指向一段英文文本
【输出】 pOutputHotWord: 输出字符串,返回出现次数最多的单词,该指针所指存储空间已经分配好,且足够大
pOutputColdWord:输出字符串,返回出现次数最少的单词,该指针所指存储空间已经分配好,且足够大
【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出
#include<vector>#include<algorithm> //使用了count计算了vector<string>中string出现的次数#include<string>using namespace std;void WordStat(const char * pInputStr, char * pOutputHotWord, char * pOutputColdWord){ unsigned int len = strlen(pInputStr); unsigned iStart=0,iEnd = 0; vector<string> vs;//vs记录string for(unsigned i=0;i<len;i++) { while(pInputStr[i]==‘ ‘||pInputStr[i]==‘.‘||pInputStr[i]==‘,‘) i++; iStart = i; while(pInputStr[i]!=‘ ‘&&pInputStr[i]!=‘.‘&&pInputStr[i]!=‘,‘&& pInputStr[i]!=‘\0‘)//在for循环中用while一定要考虑到结束条件‘\0‘ i++; iEnd = i; string s(iEnd-iStart,‘0‘); //定义的string大小就是s.size()的大小,和‘\0‘无关,string的结尾不用赋值‘\0‘ strncpy(&s[0],pInputStr+iStart,iEnd-iStart); for(unsigned j=0;j<s.size();j++)//把s中word转换成小写 { if(s[j]>=‘A‘ && s[j]<=‘Z‘) s[j]=s[j]+‘a‘-‘A‘; } vs.push_back(s);//将s存到vector中 } unsigned iMax=0,iMin=vs.size(),num; //注意最小出现次数iMin一定要初始化比较大,否则后面没法比 for(vector<string>::size_type i=0;i!=vs.size();i++) { num = count(vs.begin(),vs.end(),vs[i]); if(num>iMax) { iMax=num; strcpy(pOutputHotWord,&vs[i][0]);//用strcpy第二个参数要写成&s[0]; } if(num<iMin) { iMin = num; strcpy(pOutputColdWord,&vs[i][0]); } } }void main(){ const char* input = "lv Lv xue ,ying Xue .XUE Y enblk"; char output1[20],output2[20]; WordStat(input,output1, output2); puts(output1); puts(output2); }
本程序的数据结构分析:
(1)不能用map<char*,int>,如果用char*存字符串,则没循环一次找到一个新的字符串s,char*存放的是s的地址,上一次的地址
被回收,新的地址和上次的地址很有可能一样,但存的字符串却不是同一字符串,所以int记录的字符串出现的次数会出错。
(2)不能用map<string,int>,这样写的初衷是把每个string作为键值存起来,int作为对于键值出现的次数。但是map和set一样,是以
键值默认进行排序的。所以我们不能编写map和set的排序函数sort().同时,即使我们找到int值最大和最小的字符串,因为有可能多个
int值相同,那么要找出最先出现的string作为结果返回,由于map已经自动排序,就不能分辨出哪个是最先出现的了,所以用map也不是好的选择。
(3)用vector<string>比较合适,把每个string按顺序push_back,然后选则在vector中出现次数最多和最少的字符串返回。
如果出现次数相同,可以按照string在vector中的先后次序返回需要的较早出现的字符串。