1071 Speech Patterns (25分)
题意
令“单词”的定义为大小写字母、数字的组合。给出一个字符串,问出现次数最多的单词及其出现次数(一切除了大小写字母、数字之外的字符都作为单词的分隔符)。其中字母不区分大小写,且最后按小写字母输出。
思路
算法主要分为两个步骤:从给定字符串中分割出“单词”、计数出现次数最多的单词。
-
由题意可知,单词由大小写字母、数字组成(不妨称为有效字符),且由除有效字符外的字符进行分割,因此不妨枚举字符串中的字符,如果该字符是有效字符,则将其加入当前单词中(如果是大写字母,则将其替换为对应的小写字母);如果该字符不是有效字符,则跳过。之后跳过非有效字符,进行下一个单词的组合。
-
遍历map中的所有元素,获取出现次数最多的单词。
string s;
unordered_map<string,int> mp;
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()
{
getline(cin,s);
for(int i=0;i<s.size();i++)
{
if(check(s[i]))
{
string word;
int j=i;
while(j<s.size() && check(s[j])) word+=tolower(s[j]),j++;
mp[word]++;
i=j;
}
}
string res;
for(auto t:mp)
{
if(!res.size()) res=t.fi;
else if(t.se > mp[res]) res=t.fi;
else if(t.se == mp[res] && t.fi < res) res=t.fi;
}
cout<<res<<' '<<mp[res]<<endl;
//system("pause");
return 0;
}
用strtok函数try了一下,猜分割符猜的心累,最后发现少给个-
,然后就\(\color{green}{AC}\)了。
ps:由于gets()已经死了,就用的正则表达式。
const int N=1048576+10;
char s[N];
char split[]=".?!,\": @#$%^&*()<>{}[]\'\\/-";
map<string,int> mp;
int main()
{
scanf("%[^\n]",s);
char* token = strtok(s,split);
while(token != NULL)
{
int len=strlen(token);
for(int i=0;i<len;i++) token[i]=tolower(token[i]);
mp[token]++;
token = strtok(NULL,split);
}
string res;
for(auto t:mp)
{
if(!res.size()) res=t.fi;
else if(t.se > mp[res]) res=t.fi;
else if(t.se == mp[res] && t.fi < res) res=t.fi;
}
cout<<res<<' '<<mp[res]<<endl;
//system("pause");
return 0;
}