PAT 甲级 1022 Digital Library (30分)

原题链接1022 Digital Library (30分)

题目大意:

一本书,只有一位作者,包含的关键词不超过 5 个。
总共不超过 1000 个不同的关键词,不超过 1000 个不同的出版商。
图书信息介绍完毕后,有一行包含一个整数 M,表示查询次数。

当读者查询某一关键信息时,你应该找到所有与查询相关的书籍,并将它们按 ID 的升序排序输出。

分析:

难点和重点在于:对字符串的读入和处理。
有格式的字符串用 scanf() 比较好
普通无空格字符串用cin
包含空格的字符串用 getline(),且注意用 getchar 读上一行剩下的回车
一行有未知数目的字符串,要用 stringstream
如本题中的图书关键词:

vector<string> keywords;
string keyword;
string line;
getline(cin, line)
stringstream ssin(line)
while(ssin >> keyword) {
	keywords.insert(keyword)
}

这样,就将 line 分割成单个 keyword 存入 keywords 中了。

其次是对查找进行处理
首先,对读入的问题进行输出,然后用 string 的 substr 切割后边的问题,用第 0 个字符判断提问。将每次将符合条件的 id insert 到 set < string > 中,默认就是升序排列的。

满分代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <sstream>
#define inf 0x3f3f3f3f
typedef long long LL;
using namespace std;
const int MAXN = 1e3+10;

struct Book {
	string id, name, author;
	set<string> keywords;
	string publisher, year;
};

int main() {
	int n, m;
	cin >> n;
	vector<Book> books;
	for(int i = 0; i < n; i++) {
		string id, name, author;
		set<string> keywords;
		string keyword, publisher, year;
		cin >> id;
		getchar();
		getline(cin, name);
		getline(cin, author);
		// 一行读分 将一行的多个字符串 分隔成单个字符串 
		string line;
		getline(cin, line);
		stringstream ssin(line);
		while(ssin >> keyword) {
			keywords.insert(keyword);
		}
		
		getline(cin, publisher);
		cin >> year;
		books.push_back({id, name, author, keywords, publisher, year});
	}
	cin >> m;
	getchar();
	string que;
	while(m--) {
		// 在使用getline()之前要读入上一行的回车 
		getline(cin, que);
		cout << que << endl;
		string info = que.substr(3);
		set<string> ids;
		if(que[0] == '1') {
			for(auto& p: books) {
				if(p.name == info) {
					ids.insert(p.id);
				}
			}
		} 
		else if(que[0] == '2') {
			for(auto& p: books) {
				if(p.author == info) {
					ids.insert(p.id);
				}
			}
		}
		else if(que[0] == '3') {
			for(auto& p: books) {
				if(p.keywords.count(info)) {
					ids.insert(p.id);
				}
			}
		}
		else if(que[0] == '4') {
			for(auto& p: books) {
				if(p.publisher == info) {
					ids.insert(p.id);
				}
			}
		}
		else if(que[0] == '5') {
			for(auto& p: books) {
				if(p.year == info) {
					ids.insert(p.id);
				}
			}
		}
//		sort(ids.begin(), ids.end());
		if(!ids.size()) {
			cout << "Not Found" << endl;
		} else {
			for(auto & k: ids) {
				cout << k << endl;
			}
		}
	}
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值