AcWing 1557. 说话方式
原题链接
简单
作者:
锦梨冲冲冲
,
2020-04-03 22:42:29
,
所有人可见
,
阅读 894
(一)解题逻辑
输出出现频率最高的单词 不区分大小写 都当成小写字母来判断
①读入一整行,getline(cin,str)
②提取字符串中的每个单词
类似双指针算法
for(i=0;i<str.size();i++)//外重循环遍历整个字符串
if 如果是字母或数字,则是整个单词的第一个字母//非单词部分,可以直接忽略,考虑所有是字母部分的字符
//把整个单词找出来
j=i;
while(j<str.size() && ) 只要j在范围内并且第j个字符也是字母或数字
j++;
i=j; 因为最后i要加加
循环结束后,i到j之间是完整的单词
i到j-1构成一个单词
再用哈希表存储它的个数
(二)tolower(_)函数的内部逻辑
char to_lower(char c)
{
if(c >= 'A' && c<= 'Z') return c + 32;//大写+32就变成小写了
else return c;
}
闫式优美题解
#include<iostream>
#include<unordered_map>
using namespace std;
bool check(char c)//如果当前字符是字母或数字的话,就是单词字母
{
if(c >= '0' && c <= '9') return true;
if(c >= 'A' && c <= 'Z') return true;
if(c >= 'a' && c <= 'z') return true;
return false;
}
int main()
{
string str;
getline(cin, str);
unordered_map<string,int> hash;//初始化一个int型哈希表
for(int i = 0; i < str.size() ; i++)//从前往后遍历整个字符串
if(check(str[i]))//如果当前字符是我们需要的字符,就把当前这个单词抠出来
{
string word;
int j = i;
while ( j < str.size() && check(str[j]))
//当j比边界小同时str[j]是字母或数字的话,word就加上这个字符
word += tolower(str[j++]);
//tolower()函数,如果是大写字母就变成小写,如果是小写字母就变成大写
//把整个单词抠出来了
hash[word] ++ ;//在hash表里把单词逐个+1
i = j;
}
//求哈希表中出现次数最多的单词
string word;
int cnt = -1;
for (auto item : hash)
//item.first 字符串 item.second次数
if (item.second > cnt || item.second == cnt && item.first < word)
//如果次数大于count或者 次数等于count 并且字典序小于当前单词,就把次数最多的单词更新一下
{
word = item.first;
cnt = item.second;
}
cout << word << ' ' << cnt << endl;
return 0;
}
也可以使用map做hash表
这样在最后遍历求答案的时候不需要判断item.second == cnt && item.first < word这两个条件
因为map已经按照字典序排序,找到的第一个item.second最大的就是答案,后面的即使item.second和当前cnt相等,字典序也一定比当前大,肯定不是答案