Engine-字符串

来源:互联网 发布:jo malone推荐知乎 编辑:程序博客网 时间:2024/06/05 23:03

问题 : Engine-字符串

时间限制: 1 Sec  内存限制: 128 MB
提交: 624  解决: 300

题目描述

谷歌、百度等搜索引擎已经成为了互连网中不可或缺的一部分。在本题中,你的任务也是设计一个搜索论文的搜索引擎,当然,本题的要求比起实际的需求要少了许多。
本题的输入将首先给出一系列的论文,对于每篇论文首先给出标题,然后给出它被引用的次数。然后会有一系列的搜索询问,询问标题中包含特定关键词的论文有哪些。
每一个询问可能包含多个关键词,你需要找出标题包含所有关键词的论文。
“包含”必须是标题中有一个词正好是给定的关键词,不区分大小写。
对每个询问,都按被引用的次数从多到少输出满足条件的论文的标题。如果有被引用的次数相同的论文,则按照论文在输入中的顺序排列,先给出的论文排在前面。

输入

输入包含多组数据。
每组数据首先有一行包含一个整数N(1<=N<=1000),表示论文的数目,N=0表示输入结束。每组论文的信息第一行是论文的标题,由字母(大小写均可)和空格组成,不超过10个词,每个词不超过20个字符,标题总共不超过250个字符。第二行是一个整数K(0<=K&lt;=108),表示它被引用的次数。在论文信息结束以后,有一行包含一个整数M(1<=M<=100),表示询问的数目。接下来有M行,每行是一个询问,由L(1<=L<=10)个空格分开的词构成,每个词不超过20个字符。

输出

对每个询问,按照题目给定的顺序输出满足条件的论文的标题;如果没有满足条件的论文,就不输出。在每组询问的输出之后输出一行“***”,在每组数据的输出之后输出一行“---”。

样例输入

6Finding the Shortest Path120Finding the k Shortest Path80Find Augmenting Path in General Graph80Matching in Bipartite Graph200Finding kth Shortest Path50Graph Theory and its Applications406shortest pathk shortest pathgraphpathfindapplication0

样例输出

Finding the Shortest PathFinding the k Shortest PathFinding kth Shortest Path***Finding the k Shortest Path***Matching in Bipartite GraphFind Augmenting Path in General GraphGraph Theory and its Applications***Finding the Shortest PathFinding the k Shortest Path Find Augmenting Path in General GraphFinding kth Shortest Path***Find Augmenting Path in General Graph******---

解题思路:

在我看来,这一道题也是关于字符串的问题,属于字符串匹配。

首先我们想一下这一道题有什么需要关注的

1、这道题大小写不敏感

2、对于输出,有着引用倒叙的要求,以及相同引用次数的情况下按照输入顺序来进行输出。

3、要对关键词进行匹配。


首先我们看一下怎么解决

1、可以使用Ascii码进行求解

2、可以使用倒序排序

3、可以使用find()函数;


再看看这一道题,输入的样例,我们可以把每一个标题都看成是一个“对象”,有着标题和引用次数两个数据成员。这样子我们就可以使用一个自己建造的类初始化对象数组,分别存储。

存储完之后可以进行一次“复制”操作,即初始化一个对象数组,不过这时候的标题就已经是统一“小写化”

之后要匹配的关键词,也要进行“小写化”

最后匹配的时候用find()函数进行匹配

这道题还有一个难点就是

我们使用find()函数的话可能会出现下面这种情况

我们匹配关键词man

superman is a hero 这个标题也会被匹配出来

这就是一个很严重的问题,因为显然man并不是一个独立的单词,只是一个单词里面的一个部分

这样子如何解决呢?

没错。

我们应该把要匹配的标题和关键词,首尾都加上一个空格。

这样子就可以完美的解决这个问题


代码展示:

#include<iostream>#include<string>using namespace std;class article//新建了一个类 {public:article(){s="";visit=0;}string s;int visit;};int main(){article art[1000];//对象数组,用来存储原来的输入 article art2[1000];//“小写化”后存储的对象数组 int n=0;while(cin>>n){if(n==0)break;cin.get();for(int i=0;i<n;i++){art[i].s=" ";//首加上空格 string tmp;getline(cin,tmp); art[i].s=art[i].s+tmp;art[i].s+=" ";//尾加上空格 cin>>art[i].visit;cin.get();art2[i]=art[i];//这里不是浅拷贝 for(int j=0;j<art2[i].s.length();j++)//小写化 {if(art2[i].s[j]>='A'&&art2[i].s[j]<='Z')art2[i].s[j]+=32;}}int m=0;cin>>m;cin.get();article headings[1000];//用来存储可能符合要求的标题 for(int i=0;i<m;i++){string keys=" ";//关键词首加上空格 string tmp;getline(cin,tmp);keys+=tmp;keys+=" ";//关键词尾加上空格 for(int i=0;i<keys.length();i++)//小写化 {if(keys[i]>='A'&&keys[i]<='Z')keys[i]=keys[i]+32;}int k=0;for(int i=0;i<n;i++){if(art2[i].s.find(keys)!=string::npos)//进行匹配 {headings[k].s=art[i].s;//匹配成功就进行赋值 headings[k].visit=art[i].visit;k++;}}for(int i=k-1;i>0;i--)//这个排序按照倒序是因为保证不打乱相同引用次数的情况下的输入顺序 {for(int j=i-1,tmp=0;j>=0;j--){string tmp2;if(headings[i].visit>headings[j].visit){tmp=headings[i].visit;headings[i].visit=headings[j].visit;headings[j].visit=tmp;tmp2=headings[i].s;headings[i].s=headings[j].s;headings[j].s=tmp2;}}}for(int i=0;i<k;i++)//输出的时候去掉我们为了匹配加上的空格就好了 {headings[i].s.erase(0,1);headings[i].s.erase(headings[i].s.length()-1,1);cout<<headings[i].s<<endl;}cout<<"***"<<endl;}cout<<"---"<<endl;}}