PAT A1022 Digital Library (30 分)

A Digital Library contains millions of books, stored according to their titles, authors, key words of their abstracts, publishers, and published years. Each book is assigned an unique 7-digit number as its ID. Given any query from a reader, you are supposed to output the resulting books, sorted in increasing order of their ID’s.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤10​4​​) which is the total number of books. Then N blocks follow, each contains the information of a book in 6 lines:

Line #1: the 7-digit ID number;
Line #2: the book title – a string of no more than 80 characters;
Line #3: the author – a string of no more than 80 characters;
Line #4: the key words – each word is a string of no more than 10 characters without any white space, and the keywords are separated by exactly one space;
Line #5: the publisher – a string of no more than 80 characters;
Line #6: the published year – a 4-digit number which is in the range [1000, 3000].

It is assumed that each book belongs to one author only, and contains no more than 5 key words; there are no more than 1000 distinct key words in total; and there are no more than 1000 distinct publishers.
After the book information, there is a line containing a positive integer M (≤1000) which is the number of user’s search queries. Then M lines follow, each in one of the formats shown below:

1: a book title
2: name of an author
3: a key word
4: name of a publisher
5: a 4-digit number representing the year

Output Specification:
For each query, first print the original query in a line, then output the resulting book ID’s in increasing order, each occupying a line. If no book is found, print Not Found instead.

Sample Input:

3
1111111
The Testing Book
Yue Chen
test code debug sort keywords
ZUCS Print
2011
3333333
Another Testing Book
Yue Chen
test code sort keywords
ZUCS Print2
2012
2222222
The Testing Book
CYLL
keywords debug book
ZUCS Print2
2011
6
1: The Testing Book
2: Yue Chen
3: keywords
4: ZUCS Print
5: 2011
3: blablabla

Sample Output:

1: The Testing Book
1111111
2222222
2: Yue Chen
1111111
3333333
3: keywords
1111111
2222222
3333333
4: ZUCS Print
1111111
5: 2011
1111111
2222222
3: blablabla
Not Found

题意(除了个人评论外均出自葵花宝典)

给出N本书的编号、书名、作者、关键词(可能还有多个)、出版社以及出版年份,并给出M个查询,各个查询给出书名、作者、关键词(单个)、出版社以及出版年份中的一个,按要求满足该给出信息的所有书的编号。

思路:

  1. 利用map<string, set>来读入信息。|| 一开始我的想法是定义一个string到int的映射,然后有关keyword的地方使用多个数组,但是这种想法实现起来很麻烦并且很容易因为数据庞大超时。而葵花宝典给出的建议是看准了这道题的主要特性是string对应多个int,从output就可以看出,而我最初的想法是没有理解成功这道题目的意思,只是一味地想着用map,没想到使用map和set的组合,这里运用的是map的键和值都可以是STL容器的特性。
  2. 对于按照编号从小到大输出要求,set中的自动去重排序可以直接解决这个问题。
  3. 值得一提的是关键词的提取,由于每本书有多个关键词,所以需要将这些关键词分离开来,所以有了下面的代码:
while(cin >> s3)
{
 	key[s3].insert(id);
 	c = getchar();
  	if(c == '\n') break;
}
  1. 我觉得题目不难,但是对STL容器的使用不够熟练。

注意点:

  1. 如果单独把查询操作提炼成一个函数,那么一定要对参数使用引用,否则最后一组数据会超时。由此可见,字符串以及map的参数传递速度较慢,作为函数的参数时,尽可能加上引用。
  2. 读入编号id后,注意用getchar接受掉后面的空格,否则getline读入的会是一个空集,也就是说读入之后字符串显示为空。

代码如下:

#include<iostream>
#include<cstdio>
#include<string>
#include<set>
#include<map>
using namespace std;
map<string, set<int> > title, author, key, pub, year;
void find(map<string, set<int> >& mp, string& str)            //引用的目的在于减少时间消耗
{
    if(mp.find(str) == mp.end()) printf("Not Found\n");
    else
    {
        for(set<int>::iterator it = mp[str].begin(); it != mp[str].end(); it++)
        {
            printf("%07d\n", *it);
        }
    }
}
int main()
{
    int n, m, id, type;
    string s1, s2, s3, s4, s5;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &id);
        char c = getchar();
        getline(cin, s1);
        title[s1].insert(id);
        getline(cin, s2);
        author[s2].insert(id);
        while(cin >> s3)
        {
            key[s3].insert(id);
            c = getchar();
            if(c == '\n') break;
        }
        getline(cin, s4);
        pub[s4].insert(id);
        getline(cin, s5);
        year[s5].insert(id);
    }
    string temp;
    scanf("%d", &m);
    for(int i = 0; i < m; i++)
    {
        scanf("%d: ", &type);
        getline(cin, temp);
        cout << type << ": " << temp << endl;
        if(type == 1) find(title, temp);
        else if(type == 2) find(author, temp);
        else if(type == 3) find(key, temp);
        else if(type == 4) find(pub, temp);
        else find(year, temp);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值