写在前面
这题真的是支棱了一个上午,可恶啊,中间出了些简单的bug但是找了好久,可恶啊!!!
【问题描述】
谷歌、百度等搜索引擎已经成为了互连网中不可或缺的一部分。在本题中,你的任务也是设计一个搜索论文的搜索引擎,当然,本题的要求比起实际的需求要少了许多。
本题的输入将首先给出一系列的论文,对于每篇论文首先给出标题,然后给出它被引用的次数。然后会有一系列的搜索询问,询问标题中包含特定关键词的论文有哪些。
每一个询问可能包含多个关键词,你需要找出标题包含所有关键词的论文。
“包含”必须是标题中有一个词正好是给定的关键词,不区分大小写。
对每个询问,都按被引用的次数从多到少输出满足条件的论文的标题。如果有被引用的次数相同的论文,则按照论文在输入中的顺序排列,先给出的论文排在前面。
【输入形式】
每组数据首先有一行包含一个整数N(1<=N<=1000),表示论文的数目,N=0表示输入结束。每组论文的信息第一行是论文的标题,由字母(大小写均可)和空格组成,不超过10个词,每个词不超过20个字符,标题总共不超过250个字符。第二行是一个整数K(0<=K<=108),表示它被引用的次数。在论文信息结束以后,有一行包含一个整数M(1<=M<=100),表示询问的数目。接下来有M行,每行是一个询问,由L(1<=L<=10)个空格分开的词构成,每个词不超过20个字符。
【输出形式】
对每个询问,按照题目给定的顺序输出满足条件的论文的标题;如果没有满足条件的论文,就不输出。在每组询问的输出之后输出一行“***”,在每组数据的输出之后输出一行“—”。
【样例输入1】
6
Finding the Shortest Path
120
Finding the k Shortest Path
80
Find Augmenting Path in General Graph
80
Matching in Bipartite Graph
200
Finding kth Shortest Path
50
Graph Theory and its Applications
40
6
shortest path
k shortest path
graph
path
find
application
0
【样例输出1】
Finding the Shortest Path
Finding the k Shortest Path
Finding kth Shortest Path
***
Finding the k Shortest Path
***
Matching in Bipartite Graph
Find Augmenting Path in General Graph
Graph Theory and its Applications
***
Finding the Shortest Path
Finding the k Shortest Path
Find Augmenting Path in General Graph
Finding kth Shortest Path
***
Find Augmenting Path in General Graph
***
***
---
【样例输入2】
1
Finding the Shortest Path
120
2
Path
Pat
0
【样例输出2】
Finding the Shortest Path
***
***
---
题解
思路
- 1.name不区分大小写,所以我们统一转换为小写,但是又要保留原来的名字,所以,我们写一个结构体,有name和ture_name
- 2.我们的查询是单词查询,比如查询find,那么finding是不匹配的,所以,我们用map来存储切割好的单词,用find和count方便查询
- 3.我们查询的时候同样要切割,vector存储,每个单词就查询,每个单词都有,就是我们的结构
- 4.当然我们输出的结果是需要排序的,所以,我们前面的结构体配合vector可以进行排序
- 注意:先排序再查询输出出来的结果也是排序的,因为我们是从引用数从大到小的开始找的,所以输出的也是这个顺序。
代码
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<sstream>
using namespace std;
/******************将字符串全部转换为小写的函数************************/
string to_lower(string str){
for(int i=0;i<str.length();i++){
if(isupper(str[i])){
str[i]=tolower(str[i]);
}
}
return str;
}
/******************将字符串切割为单词存储到map,方便查询************************/
map<string,int> to_word_map(string str){
map<string,int> temp;
stringstream ss;
ss<<str;
while(ss>>str){
temp[str]=1;
}
return temp;
}
/******************将字符串切割为单词存储到vector,方便查询************************/
vector<string> to_word_vector(string str){
vector<string> temp;
stringstream ss;
ss<<str;
while(ss>>str){
temp.push_back(str);
}
return temp;
}
/*****************************论文结构体*******************************/
struct paper{
map<string,int> name;//忽略大小写,用于查询
string true_name;
int quote;
};
/***************************vector排序规则*****************************/
bool cmp(paper a,paper b){
return a.quote>b.quote;
}
int main(){
int n,k;
while(cin>>n){
if(!n) break;
vector<paper> res;
while(n--){
paper temp;
cin.ignore();//忽略换行符
getline(cin,temp.true_name);//获取整行字符串
temp.name=to_word_map(to_lower(temp.true_name));//转换为小写再切割单词存到map
cin>>temp.quote;
res.push_back(temp);
}
sort(res.begin(),res.end(),cmp);//先进行排序后再查询出来的结构自然是排序的
cin>>k;
cin.ignore();
while(k--){
string check;
getline(cin,check);
check=to_lower(check);
/**********************查询比较麻烦,不能直接find**************************/
/**********************所以我们要做一个单词切割****************************/
vector<string> check_word=to_word_vector(check);//切割存储到vector
for(int i=0;i<res.size();i++){//遍历排序好的论文
int j;
for(j=0;j<check_word.size();j++){//一个单词一个单词的去找
if(res[i].name.find(check_word[j])==res[i].name.end())
break;
}
if(j==check_word.size()) cout<<res[i].true_name<<endl; //如果每个单词都找到了就输出
}
cout<<"***"<<endl;
}
cout<<"---"<<endl;
}
return 0;
}