PAT_A1071
PAT甲级1071.
目录
A1071
题目
样例
输入:
Can1: "Can a can can a can? It can!"
输出:
can 5
思路和坑点
思路一:从序列中读取一个符合单词定义的字符串,使用map容器统计每一个单词的出现次数,然后取其出现次数最大者。
思路二:将整个字符串一次性读入,然后做预处理,将所有不构成单词的字符替换为空格,然后把数组和字母全改为小写。之后,分每个单词的读出并统计
坑点:
单词的定义:连续出现的只有字母或者数字构成的混合串。这些单词是被其他字符(非组成单词的字符,或者行末和行开头)分隔开的。比如can**me或者peng3-p2ang等这种情况算所两个单词,因为其中有两个连续的混合串。
AC代码(思路一)
#include<bits/stdc++.h>
using namespace std;
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
string s;
getline(cin,s); //使用s记录整个字符串
string word,ans; //word记录每一个单词
unordered_map<string,int> mp; //映射每一个单词的个数
int maxcnt=0;
for(int i=0;i<s.size();){
word.clear(); //每次记录新单词前,清空word
if(isalpha(s[i])||isdigit(s[i])){ //如果遇到一个单词的开头
int j=i; //往后遍历,查看当前单词的长度
int cnt=0;
while(isalpha(s[j])||isdigit(s[j])&&j<s.size()){
cnt++; //统计单词长度
j++;
}
word=s.substr(i,cnt); //截取单词
for(int k=0;k<word.size();k++){ //转化成小写
word[k]=tolower(word[k]);
}
mp[word]++; //出现次数加一
if(mp[word]>maxcnt){ //筛选最大次数的词语
maxcnt=mp[word];
ans=word;
}
i=j; //i指向该单词在串中的下一个位置
}
else
i++; //如果不是单词的开始,跳过到下一个字符
}
cout<<ans<<' '<<mp[ans]; //输出结果
return 0;
}
AC代码(思路二)
#include<bits/stdc++.h>
using namespace std;
int main(void){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
string s;
string temp;
unordered_map<string, int>mp;
getline(cin, s);
for (int i = 0; i < s.size(); i++){
if (!isalpha(s[i]) && !isdigit(s[i]))
s[i] = ' ';
else
s[i] = tolower(s[i]);
}
for (int i = 0; i < s.size(); i++){
if (s[i] == ' ' || i == s.size() - 1){
if (i == s.size() - 1 && s[i] != ' '){
temp += s[i];
}
if (temp.size()>0){
mp[temp]++;
}
temp.clear();
}
else
temp += s[i];
}
string ans;
int cnt = 0;
for (auto it = mp.begin(); it != mp.end(); it++){
if (it->second > cnt){
ans = it->first;
cnt = it->second;
}
else if (it->second == cnt && it->first < ans){
ans = it->first;
}
}
cout << ans << " " << cnt;
return 0;
}