题目
原题链接
给出一行字符串,请统计其中出现次数最多的单词,打印出该单词的小写形式和对应次数。
给的字符串可能什么字符都有,以'\n'
结尾。这里的单词定义为连续的字母数字混合序列。
例如InputCan1: "Can a can can a can? It can!"
的词汇表为:can1, can, a, it
思路
- 处理输入
因为要求把单词都改成小写的形式,所以输入字符串时就将大写字母转化成小写字母再存入字符数组,并且用空格作为两个单词之间的分隔符。 - 单词分割
strtok()函数char *strtok(char *str, const char *delim)
,str – 要被分解成一组小字符串的字符串。delim – 包含分隔符的 C 字符串。返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。如果要处理所有的分解结果,需要用一个while
循环结构,详见代码 - 次数统计
使用map
进行统计,一个单词作为一个key,次数是value。这里注意,如果用char*
作为key,存入的实际是变量的地址,因为strtok()
的分割结果地址都不一样,所以即使是相同的两个单词,都会当做不同的key。所以这里将char*
转为string
作为key,直接赋值即可完成转换
AC代码
#include<bits/stdc++.h>
#define MAXN 1048576
using namespace std;
char Lower[MAXN+1]; //存放字符串
int main(){
char c;
int i = 0; //Lower数组的下标
while((c = getchar())!='\n'){
if(c>='a'&&c<='z'||c>='0'&&c<='9'||c>='A'&&c<='Z'){
/* 大写转小写 */
if(c>='A'&&c<='Z')
Lower[i++] = c+32;
else Lower[i++] = c;
}else if(i>=1 && Lower[i-1]!=' '){
Lower[i++] = ' ';
}
}
Lower[i] = '\0';
map<string,int> m; //如果用char*作为key会有问题
/* 获取第一个子字符串 */
char* token = strtok(Lower, " ");
/* 继续获取其他的子字符串 */
while( token != NULL ) {
string stoken = token; //char* 转 string,直接赋值即可
m[stoken]++;
token = strtok(NULL, " ");
}
string mostComm; //出现次数最多的单词
int maxUsed = 0; //最大出现次数
for(map<string, int>::iterator it = m.begin();it!=m.end();++it){
if(it->second > maxUsed){
maxUsed = it->second;
mostComm = it->first;
}
}
cout<<mostComm<<" "<<maxUsed;
return 0;
}