A Speech Patterns (25)
原题为英文,用谷歌浏览器翻译了一下
题目描述
人们通常对同一个词的同义词有偏好。例如,有些人可能更喜欢“警察”,而另一些人可能更喜欢“警察”。分析此类模式有助于缩小说话者的身份,这在验证例如在线头像背后是否仍然是同一个人时很有用。
现在给定一段从某人的演讲中抽取的文本,你能找到这个人最常用的词吗?
输入
每个输入文件包含一个测试用例。对于每种情况,都有一行长度不超过 1048576 个字符的文本,以回车符“\n”结束。输入包含至少一个字母数字字符,即来自集合 [0-9 AZ az] 的一个字符。
输出
对于每个测试用例,在一行中打印输入文本中最常出现的单词,后跟一个空格和它在输入中出现的次数。如果有多个这样的单词,则打印按字典顺序最小的单词。该单词应全部小写。这里的“单词”被定义为由非字母数字字符或行开头/结尾分隔的字母数字字符的连续序列。
请注意,单词 不区分大小写。
样例输入
Can1: “Can a can can a can? It can!”
样例输出
can 5
代码提交
#include <iostream>
#include<map>
#include<string>
#include<stdio.h>
#include<algorithm>
using namespace std;
//单词分割中将符合词的字母进行判断,排除掉空格和标点
bool check(char c){
if(c>='a'&&c<='z') return true;
if(c>='A'&&c<='Z') return true;
if(c>='0'&&c<='9') return true;
return false;
}
int main()
{
//定义一个用来记录单词出现次数的map容器
map<string,int> count;
string str;//存放需要分割的语句
getline(cin,str);//读入
for(int i=0;i<str.length();i++){
string word; //word用于存放分割后的单词
while(i<str.length() &&check(str[i])==true){
if(str[i]>='A'&&str[i]<='Z'){
str[i]+=32;
}
word+=str[i];
i++;
}
if(word!=""){
if(count.find(word)==count.end()){
count[word]=1; //如果word分割在之前没有出现,即第一次出现,将个数定义为1
}
else{
count[word]++;
}
}
}
string maxword; //出现最多的单词
int max=0; //出现的次数
for(map<string,int>::iterator it=count.begin();it!=count.end();it++){
if(it->second>max){
max=it->second;
maxword=it->first;
}
}
cout << maxword<<" " <<max<< endl;
return 0;
}
思路
这种题目相当于单词分割的题型
1.单词分割是通过非法字符来分割的,因此设置boll check()函数。
2.在map中可以通过find 函数判断是否存在,如果存在返回地址,不存在则返回map.end()。
3.由于单词分割中的word是好几个字符,因此需要设置map<string,int>而不是<char,int>。
4.通过非法字符来分割单词时应该用while循环,只有这样才能保证word有好几个char字母,而不会是单个char。
所犯错误
1.map.count定义错误,忽略了char与string区别
2.分割单词的过程使用的是if,导致最后的运行结果为a和a出现的次数。