欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PAT甲级 1022 Digital Library (30分)

程序员文章站 2024-03-17 21:26:16
...

1022 Digital Library (30分)

题目链接:PAT A 1022
PAT甲级 1022 Digital Library (30分)
PAT甲级 1022 Digital Library (30分)
PAT甲级 1022 Digital Library (30分)

题目大意:有一数字图书馆,对于每一本书给出如下信息:书的id,书的名字,书的作者,书的关键字,书的出版社以及书的出版年份。要求根据输入的查找信息输出相应书的ID(7位数字)。

思路分析:这道题题意很直观,但是需要用到的知识点比较多。首先根据题目要求可以分析出这道题一定是使用STL中的map去解决,而且由于题目中说书的某个属性可能对应好几个ID,所以不能使用一般的map解决,要用到嵌套的STL容器,一开始我想到的是map<string, vector >,但是题目中要求输出的ID是按照序号递增的顺序去输出,所以vector不能解决问题,这就要用到set了,因为set容器会对容器中的元素自动排序,恰好符合题目要求。ps:如果不知道怎么访问这种叠加类型的容器,可以百度查找一下,详细学习相关操作。

注意点1:由于题目中很多属性的字符串中是可能带有空格的,而cin遇到空格就会停止输入,所以这时候就要用到getline,getline可以读入带空格的字符串。但是如果前一个语句是cin或者scanf,后面接getline,就必须在getline之前加上getchar(),不然getline会读入换行导致字符串为空串,不懂的可以看这篇文章:关于getline与cin

注意点2:题目中输入书的关键字那一行,由于题目不告诉有几个关键字,那怎么判断什么时候输入结束呢?是要根据换行符,设置一个变量c,如果接受到的是换行符,那么就退出while循环。(getchar可以吸收空格,回车等)。

注意点3:在这里讲一下scanf() 怎样读取输入:假定使用了一个%d说明符来读取一个整数。scanf() 函数开始每次读取一个输入字符,它跳过空白字符(空格、制表符和换行符)直到遇到一个非空白字符。

注意点4:38行的scanf与39行的getline之间没有加getchar,这是因为
scanf("%d: ", &num);引号里面有空格,编译器认为你输入的数据形式是%d+空格,你输入的空格就被填充到scanf前面的那个空格,但是没有变量接受。

注意点5:map的find函数如果没找到某个键,那么将返回map.end()

注意点6:函数中只能使用引用传参,不能是值传递,值传递传递类型为STL的容器时非常慢,会导致最后一组数据超时,改成引用传参会有非常明显的提速效果。

AC代码:

#include<iostream>
#include<set>
#include<map>
using namespace std;
void query(map<string, set<int>> &mp, string &str) {
	if(mp.find(str) == mp.end())
		printf("Not Found\n");
	else {
		for(auto it = mp[str].begin(); it != mp[str].end(); it++)
			printf("%07d\n", *it); //注意是%07d,因为id有可能是0123456这种形式 
	}
}
int main() {
	int n, m, id, num;
	string bookname, people, key, pub, nian, tempstr;
	scanf("%d", &n);
	map<string, set<int>> title, keywords, publisher, author, year;
	for(int i = 0; i < n; i++) {
		scanf("%d", &id);
		getchar();
		getline(cin, bookname);
		title[bookname].insert(id); //set容器的输入使用insert 
		getline(cin, people);
		author[people].insert(id);
		while(cin >> key) {
			keywords[key].insert(id);
			char c = getchar();
			if(c == '\n') //读入到换行符,退出while循环 
				break;
		}
		getline(cin, pub);
		publisher[pub].insert(id);
		getline(cin, nian);
		year[nian].insert(id);
	}
	scanf("%d", &m);
	for(int i = 0; i < m; i++) {
		scanf("%d: ", &num);
		getline(cin, tempstr);
		cout << num << ": " << tempstr << endl; //按题目要求输出信息 
		if(num == 1)  //分类查找 
			query(title, tempstr);
		else if(num == 2) 
			query(author, tempstr);
		else if(num == 3) 
			query(keywords, tempstr);
		else if(num == 4) 
			query(publisher, tempstr);
		else 
			query(year, tempstr);
	}
	return 0;
}

总结:此题不难,但是知识点很多很杂,还要对STL容器的用法熟练掌握,否则不能顺利AC。