解题过程的小记录,如有错误欢迎指出。
难度:三星(这道题心机好深啊(bushi))
题目分析
给出一句话,找出出现次数最多的单词
注意点
- 大小写不区分
- 带有数字的单词和不带有数字的不算做同一个单词,如can和can1
- alphanumerical的意思是字母数字都可
- lexicographically的意思是按照字典次序排序【这点因为我的代码逻辑是在输入过程中边统计最大出现次数,所以在相同出现次数的时候,出现最多的单词要进行比较,字典次序小的进行输出(不过我原来这里写错了,写成大的了,提交也没有出现问,测试点不够全面吧)】
我的解题过程
思路
- 因为单词之间有空隙,所以采用getline()来获取句子
- 因为步骤3的代码逻辑(可以先看一下步骤3),如果句子最后的一个char是字母或者数字的话,会无法将次数保存到map当中,所以输入后在句子后面自己添加一个字符,保证最后一个word有结点
- 从头扫描句子中的每一个char,判断是否是字母或者数字,如果不是的话就作为前面的一个节点,把前面获得到的word(可以包含数字)保存到map的映射中计数
- 设置变量保存最大的word的出现次数和对应的word(在扫描过程中一直比较可以得出)
- 输出结果
bug
最后一个测试点一直过不了,看了解析才知道如果是一句话的结尾没有其它的字符串的话,按照我的代码逻辑,最后一个单词就不可以被统计进去,导致出错【可以用"a"测试得出】
代码
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
map<string, int> words;
string maxword, sentence;
int maxcnt = 0;
getline(cin, sentence);
sentence += ".";
string t = "";
for (int i = 0; i < sentence.size(); i++) {
if (isalpha(sentence[i])) {
if (isupper(sentence[i])) {
t += (char)tolower(sentence[i]);
}
else t += sentence[i];
}
else if (isdigit(sentence[i])) {
t += sentence[i];
}
else {
if (t != "") {
if (words.size() == 0) maxword = t;
if (words.find(t) != words.end()) words[t]++;
else words[t] = 1;
if (words[t] == maxcnt&&t < maxword) {
maxword = t;
}
else if (words[t] > maxcnt) {
maxcnt = words[t];
maxword = t;
}
}
t = "";
}
}
cout << maxword << " " << maxcnt;
return 0;
}
dalao的代码
全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~
借鉴点
- 如果采用晴神的方法,在word全部映射后再扫描找出,出现次数最大的word和对应的次数(采用的方法是初始化max为0,然后当map中的值>max时,进行更新=>这样因为map的特性(自动按照字典序排序)就可以找出字典序最小的出现次数最多的word)
- [0-9 A-Z a-z]可以简写为cctype头⽂件⾥⾯的⼀个函数isalnum【柳神666】
if(isalnum(s[i])) {
s[i] = tolower(s[i]);//这样加进去的就一定是小写字母,如果是数字的话则不做变化
t += s[i];
}
- 本题可以对照参考柳神代码,十分简洁