我们可以利用搜索引擎搜索网页等资源,再借助一些工具就可以生成这样的“词云”:
嫑犯愁,现在不要求生成这样的词云,而是换个简单些的要求:
对于输入的若干篇新闻报道以及若干个
搜索关键词
,统计输出包含各关键词的新闻篇数,并输出包含最热关键词的新闻概要。输入格式:
输入由前后两部分组成。
第一部分是不超过
100000
篇新闻报道,每篇新闻的格式是:
- 第1行是新闻标题,长度大于零且不超过
60
。- 第2行是新闻发布日期,由
8
位数字组成,格式是yyyymmdd
(4位年+2位月+2位日)- 接下来若干行是新闻正文,总长度大于零且不超过
500
,由若干词
、标点
、空格
、换行
组成,所有字符为英文半角字符。标点
仅有,
.
?
:
!
五种,且标点都是单独出现,绝对不会出现相邻两个字符都是标点的情况。词
是由不超过30
个连续的字母、数字、符号等非空格、非换行符组成的,词不包含以上五种标点,但标点有可能紧跟在一个词的末尾。例如文本Look! There is a u-turn!
中,有五个词Look
There
is
a
u-turn
两篇新闻之间,有一行分隔符
------
(连续6个-
);全部新闻结束后,有一行分隔符######
(连续6个#
)。新闻标题和正文中保证不出现这两种分隔符。分隔符
######
之后,是第二部分,由2行组成:
- 第1行是不超过
10000
的正整数N
和不超过100000
的非负整数K
,由空格分隔。- 第2行是
N
个不超过30
位的各不相同的搜索关键词
,这些关键词仅包含小写字母、数字,不含大写字母、符号。输出格式:
输出由前后两部分组成。
首先对于每个搜索关键词
,统计新闻正文中出现该词的新闻篇数,注意:(1)仅统计新闻正文,不统计新闻标题,(2)不区分大小写,例如Alien
与alien
是相同的词,(3)区分词的时态、单复数、包含符号等各种变化形式,例如aliens
和alien
是不同的词,u-turn
和uturn
是不同的词(4)显然,若一个词在所有新闻中均未出现,则篇数为0
,(5)统计的是出现关键词的新闻篇数
,不是词出现的次数。题目保证至少有一个关键词在至少一篇新闻中出现。
对于每个搜索关键词,若该词出现篇数不低于
K
,则输出在第一部分:
- 每行一词,格式为
词:篇数
- 若不低于K篇的多于一词,则按照篇数从高到低输出;若有多于一词篇数相同,则这些词按照词的字典序(英文字母从a至b排序、数字从0至9排序,数字排在字母之前)输出
- 若不存在不低于K篇的词,则输出一行
None!
在第二部分,对于出现篇数最高、且关键词的字典序最前的词,按照新闻的输入顺序,依次输出包含这个关键词的新闻概要,每条新闻一行,格式是
新闻标题/发布日期
。输入样例:
5篇新闻,6个搜索关键词,如下所示:
ALIENS APPEARED IN NEW YORK 20200320 The New York Roadside News Agency reported that yesterday a citizen found an alien on Fifth Avenue in New York. The alien snatched a Pear u-phone from the citizen. ------ The Russians caught an alien! 20210322 BBC News reported that a Russian captured an alien in the Siberian forest. It turned out that the Russian was drunk and what he caught was a polar bear. ------ Does anyone know this bear? 20190615 Reuters reported that a lost bear was found in Paddington, London. The animal rescue organization tried to find a home for the poor bear. ------ New discoveries in Egypt 20180909 Agence France-Presse reported that Egypt discovered an unknown element in a pyramid built five thousand years ago. The pyramid is suspected to be an alien relic. ------ Are you ALIEN? 20210322 The Associated Press reported that a study by the Royal Academy of Sciences showed that 10% of the population of our planet are aliens. Too frightening! So, are you an alien? How to prove to others that you are not an alien? ###### 6 1 bear citizen about alien home academy
输出样例:
输入的
K
为1
,因此按规定顺序输出包含篇数不低于1
的关键词(alien
出现在4篇新闻中,bear
出现在2篇新闻中,about
未出现在任何新闻中,其余3词出现在1篇新闻中),并按顺序输出包含alien
的新闻概要,如下所示:alien:4 bear:2 academy:1 citizen:1 home:1 ALIENS APPEARED IN NEW YORK/20200320 The Russians caught an alien!/20210322 New discoveries in Egypt/20180909 Are you ALIEN?/20210322
思路:结构体套map会超时,必须得按照关键词找文章,不能以文章找关键词,不然猛猛超
坑点:
1.查找关键词的时候只找正文,标题不管
2.不管输出第一部分输出的是不是none,第二部分都要输出出现次数最高的关键词,题目保证了一定会有关键词被匹配;
3.不能直接用find 不然 alines 和 aline 在 找“aline” 时会被统计2次, 但是根据题意,复数形式不能算。
4.文章的标题是会重复的,日期也是,存在极端样例一天内发10篇一样标题,时间,内容的文章,(标题+时间都是一致的),所以要根据输入的顺序为文章分配编号,不然过不了。
AC代码
#include<bits/stdc++.h>
using namespace std;
int n,m,k,t,cnt=0;
struct node{
//存文章的属性信息
string title;
string time;
}mp[100086];
map<string,map<int,int> >mpp;//以关键词建索引文章
struct ans{
//存答案
int num;
vector<int>link;//存指向的文章
string key;
}lst[10086];
bool cmp(ans a,ans b){//输出排序
if(a.num!=b.num)return a.num > b.num;
return a.key < b.key;
}
int main(){
ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int now_type=0;//用来标记当前输入的是什么;
string s;
//0-标题输入 1-时间驶入 2-正文输入 3-结束
while(getline(cin,s)){
//如果是------ 表示一篇文章结束
if(s =="------"){
cnt++;//文章编号++
now_type=0;//初始化
continue;
}else if(s=="######"){
cnt++;//这里也要加
break;
}
switch(now_type){
case 0://标题输入
mp[cnt].title = s;
now_type = 1;
break;
case 1://时间输入
mp[cnt].time = s;
now_type = 2;
break;
case 2://正文输入
//对字符串进行预处理
//先全部转小写
for(int k=0;k<s.length();k++){
if(s[k]>='A'&&s[k]<='Z'){
s[k] = s[k]-'A' + 'a';
}
}
//利用stringstream字符串流切割空格
stringstream ss(s);
string s1;
while(ss >> s1){
int le = s1.length();
if(s1[le-1]=='?'||s1[le-1]=='!'||s1[le-1]==':'||s1[le-1]==','||s1[le-1]=='.'){
//擦去符号存入
s1 = s1.erase(s1.length()-1,1);
}
//mpp[关键词] -》 size就是文章篇数
mpp[s1][cnt]=1;
}
break;
}
}
cin>>n>>k;
//输入关键词
for(int i=0;i<n;i++){
cin>>s;
lst[i].key = s;
lst[i].num = mpp[s].size(); //mpp[关键词] -》 size就是文章篇数
for(auto it:mpp[s]){//遍历mpp[s]出来的就是包含S关键词的文章编号;
lst[i].link.push_back(it.first);
}
}
sort(lst,lst+n,cmp);//对结果排序
int f =0;//用来标记是否有 >K 的输出
for(int i=0;i<n;i++){
if(lst[i].num<k)continue;
f=1;
cout<<lst[i].key<<":"<<lst[i].num<<endl;
}
if(f==0){
cout<<"None!"<<endl;
}
//不管上方是否有输出,都要输出关键词篇数最多的文章
//题目数据保证一定有一个关键词能被匹配
for(auto it:lst[0].link){
cout<<mp[it].title<<"/"<<mp[it].time<<endl;
}
return 0;
}
2023/04/09 更新 优化版
#include<bits/stdc++.h>
using namespace std;
map<string,map<int,int> > mp;
map<int,string>title;
map<int,string>tim;
struct node{
string key;
int num;
}lst[10086];
bool cmp(node a,node b){
if(a.num!=b.num )return a.num > b.num;
return a.key <b.key;
}
int main(){
string s;
int now=0;
int cnt =0;
while(getline(cin,s)){
if(s=="######"){
cnt++;
break;
}
if(now == 0){
title[cnt]=s;
now=1;
}else if(now == 1){
tim[cnt]=s;
now=2;
}else if(now == 2){
if(s=="------"){
cnt++;
now = 0;
}
for(int i=0;i<s.length();i++){
if(s[i]>='A'&&s[i]<='Z')s[i] = char(s[i]-'A'+'a');
if(s[i]==',' || s[i]=='.' ||s[i]=='?' ||s[i]=='!' ||s[i]==':'){
s[i]=' ';
}
}
stringstream ss(s);
string s1;
while(ss>>s1){
mp[s1][cnt]=1;
}
}
}
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
string key;
cin>>key;
lst[i].key = key;
lst[i].num = mp[key].size();
}
sort(lst,lst+n,cmp);
int f =0;
for(int i=0;i<n;i++){
if(lst[i].num >= m){
cout<<lst[i].key<<":"<<lst[i].num<<endl;
f =1;
}else{
break;
}
}
if(f==0)cout<<"None!"<<endl;
for(auto it:mp[lst[0].key]){
cout<<title[it.first]<<"/"<<tim[it.first]<<endl;
}
return 0;
}