一 :题目
新浪微博可以在发言中嵌入“话题”,即将发言中的话题文字写在一对“#”之间,就可以生成话题链接,点击链接可以看到有多少人在跟自己讨论相同或者相似的话题。新浪微博还会随时更新热门话题列表,并将最热门的话题放在醒目的位置推荐大家关注。
本题目要求实现一个简化的热门话题推荐功能,从大量英文(因为中文分词处理比较麻烦)微博中解析出话题,找出被最多条微博提到的话题。
输入格式:
输入说明:输入首先给出一个正整数N(≤10
5
),随后N行,每行给出一条英文微博,其长度不超过140个字符。任何包含在一对最近的#中的内容均被认为是一个话题,输入保证#成对出现。
输出格式:
第一行输出被最多条微博提到的话题,第二行输出其被提到的微博条数。如果这样的话题不唯一,则输出按字母序最小的话题,并在第三行输出And k more …,其中k是另外几条热门话题的条数。输入保证至少存在一条话题。
注意:两条话题被认为是相同的,如果在去掉所有非英文字母和数字的符号、并忽略大小写区别后,它们是相同的字符串;同时它们有完全相同的分词。输出时除首字母大写外,只保留小写英文字母和数字,并用一个空格分隔原文中的单词。
输入样例:
4
This is a #test of topic#.
Another #Test of topic.#
This is a #Hot# #Hot# topic
Another #hot!# #Hot# topic
输出样例:
Hot
2
And 1 more ...
二:思路分析
思路:想办法将# #中的数据提取出来,然后用map容器进行存储m[str] +=1;如果出现相同的话题
那就加一,(没有重复的m[str]是默认为 0 的也就是最后的m[str] == 1)
接下来map容器当中最后一个值就是最大的当然可能会出现重复的但没关系,我们再根据已知
的最大值即可求取,然后相同话题的个数也就是 题目要求输出的第二项
这里我用的是set容器将每条为微博中的话题提取出来
还有需要注意的是 这道题不是让统计话题的个数最多的,是看每一条微博里提到的话题 ,无论一条微博里提到几次,都统计为这一条微博出现的话题。
三:上码
/**
思路:想办法将# #中的数据提取出来,然后用map容器进行存储m[str] +=1;如果出现相同的话题
那就加一,(没有重复的m[str]是默认为 0 的也就是最后的m[str] == 1)
接下来map容器当中最后一个值就是最大的当然可能会出现重复的但没关系,我们再根据已知
的最大值即可求取,然后相同话题的个数也就是 题目要求输出的第二项
这里我用的是set容器将每条为微博中的话题提取出来
*/
#include<bits/stdc++.h>
using namespace std;
set<string>s[100010];
set<string>:: iterator st;
//提取字符串中# #中间的内容
void deal(string str,int x){
int flag = 0;
int count = 0;
string word = "";//字符串初始化
string str1 = "";
str += "!";//给字符串末尾加个结束标志
for( int i = 0; i < str.size(); i++ ){
//This is a #test of topic#.
if( str[i] == '#'){
flag = 1;
count++;
if( i < str.size() - 1)
i++;
}
if( isalpha(str[i]) && flag == 1 || isdigit(str[i]) && flag == 1){//判断该字符是否为字母 || 数字
if( isalpha(str[i]))
word += tolower(str[i]);//将大写英文字母改为小写英文字母
if( isdigit(str[i]))
word += str[i];
}else if( flag == 1 ) {//这里flag = 1 保证取出的字符为##里头的
// cout << word << endl;
if( word != " ")
str1 += word;
word = " ";//清理掉上次的单词存入新的单词 (并且给除第一个单词外的其他单词加上空格)
}
//代表一个话题里的热点
if( count == 2){
flag = 0;
count = 0;//可能一行中有多个#号
if(str1 != " " )
s[x].insert(str1);
word = ""; //当一条语句当中,会有两遍热点话题,那么的话(因为在最后执行完str1后 word又被赋值为" ",而新的热点开头需要的是无空格)
str1.clear();
}
}
}
int main(){
int N;
map<string,int>m2;
map<string,int>::iterator t;
cin >> N;
getchar();
for( int i = 0; i < N; i++ ){
string str;
getline(cin,str);
deal(str,i);
for( st = s[i].begin(); st != s[i].end(); st++ ){
m2[*st] += 1;
}
}
// cout << "******************"<< endl;
int max = 0;
for( t = m2.begin(); t != m2.end(); t++ ){
if( t->second > max ){
max = t->second;
}
}
// cout << max << endl;
int num;
for( t = m2.begin(); t != m2.end(); t++ ){
if( t->second == max ){
string str = t->first;
str[0] = toupper(str[0]);
cout << str << endl;
cout << t->second << endl;
num = t->second;
break;
}
}
int count = -1;//把自己先排除掉
for( t = m2.begin(); t != m2.end(); t++ ){
if(t->second == num )
count++;
}
//cout << m2.size() << endl;
if( count > 0)
cout << "And " << count << " more ...";
}
//4
//This is a #test of topic#.
//
//This is a #Hot# #Hot# topic
//Another #hot!# #Hot# topic
//1
//This is a #test of topic#.
//1
//Another #hot!# #Hot# topic
//Another #Hot# topic
//4
//This is a #test of topic#.
//Another #Test of topic.# #Hot#
//This is a #Hot# #Hot# topic
//Another #hot!# #Hot# topic
//
//Another #Test1 of topic.#
//This is a #test of topic#.
//Another #hot!# #Hot# topic
四:总结
最后有一个点有刚开始一直段错误,那是因为我上方set开的范围太小了,加大范围,比题目的10的5次方大就行 加油boy!