[湖南大学程序设计实训训练作业二]8.Engine-字符串(字符串切割+结构体map存储+切割vector查询)

写在前面

这题真的是支棱了一个上午,可恶啊,中间出了些简单的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;
} 
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值