新浪微博可以在发言中嵌入“话题”,即将发言中的话题文字写在一对“#”之间,就可以生成话题链接,点击链接可以看到有多少人在跟自己讨论相同或者相似的话题。新浪微博还会随时更新热门话题列表,并将最热门的话题放在醒目的位置推荐大家关注。
本题目要求实现一个简化的热门话题推荐功能,从大量英文(因为中文分词处理比较麻烦)微博中解析出话题,找出被最多条微博提到的话题。
输入格式:
输入说明:输入首先给出一个正整数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 …
解答:
#include<iostream>
#include<map>
#include<string>
#include<vector>
using namespace std;
typedef struct T {
//提到次数
int times;
//最后一次微博提到位置
int last;
}Topic;
map<string, Topic> all_record;
vector<string> all_topic;
map<string, Topic>::iterator it;
int main() {
string text, undeal_topic;
int line, i, j, begin, end, len, start, mark_deal_pos,insert_pos=0;
cin >> line;
getchar();
bool is_space;
//读取数据
for (i = 0; i < line; i++) {
getline(cin, text);
//处理数据
mark_deal_pos = 0;
while (1) {
Topic topic;
begin = text.find('#', mark_deal_pos);
if (begin != -1) {
//下一位是否可以为空格
is_space = false;
char deal_topic[150];
start = 0;
end = text.find('#', begin + 1);
if (end != -1) {
mark_deal_pos = end + 1;
//得到未处理的话题内容
undeal_topic = text.substr(begin + 1, end - begin);
len = undeal_topic.length();
for (j = 0; j < len; j++) {
if ('a' <= undeal_topic[j] && undeal_topic[j] <= 'z') {
deal_topic[start++] = undeal_topic[j];
is_space = true;
}
else if ('A' <= undeal_topic[j] && undeal_topic[j] <= 'Z') {
deal_topic[start++] = undeal_topic[j] + 32;
is_space = true;
}
else if ('0'<=undeal_topic[j] && undeal_topic[j]<='9') {
deal_topic[start++] = undeal_topic[j];
is_space = true;
}
else if (is_space) {
deal_topic[start++] = ' ';
is_space = false;
}
}
//去除尾部空格
if (start != 0 && deal_topic[start - 1] == ' ') {
start--;
}
deal_topic[start] = '\0';
string deal_(deal_topic);
//判断是否是空话题
if (deal_.length() > 0) {
it = all_record.find(deal_);
if (it != all_record.end()) {
if (it->second.last != i) {
it->second.times++;
it->second.last = i;
}
}
else {
all_topic.insert(all_topic.begin()+insert_pos,deal_);
insert_pos++;
topic.last = i;
topic.times = 1;
all_record.insert({ deal_,topic });
}
}
}
}
else {
break;
}
}
}
//开始搜索
int max = 0, equeal_hot_times = 0;
string hot_topic;
for (vector<string>::iterator mv = all_topic.begin(); mv != all_topic.end(); mv++) {
it = all_record.find(*mv);
if (it->second.times > max) {
max = it->second.times;
hot_topic.clear();
hot_topic.append(*mv);
equeal_hot_times = 0;
}
else if (it->second.times == max) {
if (hot_topic.compare(*mv) > 0) {
hot_topic.clear();
hot_topic.append(*mv);
}
equeal_hot_times++;
}
}
hot_topic[0] -= 32;
cout << hot_topic << endl;
cout << max;
if (equeal_hot_times) {
cout << endl << "And " << equeal_hot_times << " more ...";
}
return 0;
}