7-4 新浪微博热门话题 (20 分) 新浪微博可以在发言中嵌入“话题”,即将发言中的话题文字写在一对“#”之间,就可以生成话题链接,点击链接可以看到有多少人在跟自己讨论相同或者相似的话题。新浪微博还


7-4 新浪微博热门话题 (20 分)

题目描述

新浪微博可以在发言中嵌入“话题”,即将发言中的话题文字写在一对“#”之间,就可以生成话题链接,点击链接可以看到有多少人在跟自己讨论相同或者相似的话题。新浪微博还会随时更新热门话题列表,并将最热门的话题放在醒目的位置推荐大家关注。

本题目要求实现一个简化的热门话题推荐功能,从大量英文(因为中文分词处理比较麻烦)微博中解析出话题,找出被最多条微博提到的话题。

输入格式

输入说明:输入首先给出一个正整数N(≤105),随后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<string>
#include<cmath>
#include<vector>
#include <queue>
#include <iomanip>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
int N;
struct cmp
{
    
    
	bool operator()(const pair<string, int>& p1, const pair<string, int>& p2)//作为sort函数的参数确定比较规则
	{
    
    
		if (p1.second == p2.second)return p1.first < p2.first;//当数对的二号位相同时,根据一号位升序排列
		return p1.second > p2.second;//当数对的二号位不同时,根据二号位降序排列
	}
};
map<string, int>m;//声明string与int对应的map
string s, a;
string bian(int x, int y) {
    
    //将#之间的字符串规范化
	string h = s.substr(x + 1, y - x - 1);//先截取对应部分的字符串
	string k = "";
	vector<string>ve;
	string temp = "";
	for (int i = 0; i < h.size(); i++)
	{
    
    
		if (h[i] != ' ')//判断目前位置是否是空格
		{
    
    
			if (h[i] >= 'A' && h[i] <= 'Z')//将大写字母全部变为小写
			{
    
    
				h[i] += 32;
				temp += h[i];
			}
			else if ((h[i] >= 'a' && h[i] <= 'z') || (h[i] >= '0' && h[i] <= '9'))//判断是否是小写字母或者是数字
			{
    
    
				temp += h[i];
			}
			else//除了字母和数字外的符号
			{
    
    
				if (!temp.empty() && temp[temp.size() - 1] != ' ')//如果当前读取到的字符串不为空则将空格作为一位补充到目前的字符串上
				{
    
    
					temp += " ";
				}
			}
		}
		else
		{
    
    
			while (temp[temp.size() - 1] == ' ')//将字符串右侧的空格去掉
			{
    
    
				temp = temp.substr(0, temp.size() - 1);
			}
			ve.push_back(temp);//得到的单词放入容器中
			k = k + temp + " ";
			temp = "";
		}
	}
	if (temp != "")ve.push_back(temp); k += temp;//将最后的单词放入容器
	for (int i = 0; i < k.size(); i++)
	{
    
    
		if (k[i] >= 'a' && k[i] <= 'z')
		{
    
    
			k[i] = k[i] - 'a' + 'A';//将首字母大写
			break;
		}
	}
	while (k[0] == ' ')//下面两个while是去掉得出的字符串两端的空格
	{
    
    
		k = k.substr(1, k.size() - 1);
	}
	while (k[k.size() - 1] == ' ')
	{
    
    
		k = k.substr(0, k.size() - 1);
	}
	return k;//最后得到的字符串就是可以直接作为结果的字符串输出的字符串
}
void qu() {
    
    //对读取进来的一条微博进行处理
	bool bo = true;
	int l, r;
	l = r = 0;
	vector<string>ve;
	for (int j = 0; j < s.size(); j++)
	{
    
    
		if (s[j] == '#')
		{
    
    
			if (bo) {
    
     l = j; bo = false; }//变换bo的true或false达到截取对应位置的目的
			else {
    
    
				r = j; bo = true;
			}
		}
		if (l < r)//判断是否截取到了正确的位置
		{
    
    
			a = bian(l, r);//截取话题并处理
			l = r + 1;
			j = r;
			if (std::find(ve.begin(), ve.end(), a) == ve.end()) {
    
    //判断是否已经存在当前话题
				ve.push_back(a);
				m[a]++;//如果不存在就将该话题放入容器中,防止重复记录一条微博中的重复话题
			}
		}
	}
	ve.clear();
}
int main()
{
    
    
	cin >> N;
	getchar();
	for (int i = 0; i < N; i++)
	{
    
    
		getline(cin, s);
		qu();
	}
	vector<pair<string, int>>vt(m.begin(), m.end());//将map数据类型的m中的数据存入存有pair类型的vector容器中,便于使用sort进行排序
	sort(vt.begin(), vt.end(), cmp());//对数据排序得到想要的顺序
	int av = vt.begin()->second;//vt.begin()代表的是指向vt容器第一个位置的指针,通过->访问其中的second也就是第二位数据(int)
	int h = 0;
	cout << vt.begin()->first << endl;//vt.begin()代表的是指向vt容器第一个位置的指针,通过->访问其中的first也就是第二位数据(string)
	cout << vt.begin()->second << endl;
	bool ban = false;
	for (vector<pair<string, int>>::iterator it = vt.begin(); it != vt.end(); it++)//声明一个vector<pair<string, int>>::iterator类型的指针叫做it,通过迭代操作实现访问遍历vt容器
	{
    
    
		if (it != vt.begin() && it->second == av)//判断是否存在多个热门话题
		{
    
    
			ban = true;
			h++;
		}
		else
			if (it != vt.begin() && it->second != av) {
    
    //只要有一个不是热门话题则无需判断后面的,因为vt是排好序的
				break;
			}
	}
	if (ban)cout << "And " << h << " more ..." << endl;
	return 0;
}

思路

本题目用到了map和pair的数据类型,map允许使用两种不同的数据类型来建立一一对应的关系,pair也允许这样的操作。但是pair可以存入到容器中来用sort排序,map并不能调用sort来排序,所以借助pair来对map中的数据按照某种顺序排序。该题目整体的思路就是将读入的一条条微博中的话题提取出来,进行计数和排序。比较麻烦的在于对读入的微博中的话题的处理,排序和计数的部分比较关键的是调用的数据类型,形式较为固定,写出相应的排序规则即可。

猜你喜欢

转载自blog.csdn.net/qq_51314467/article/details/123100170