0
点赞
收藏
分享

微信扫一扫

【1022】Digital Library(map)


1.题目

​​https://pintia.cn/problem-sets/994805342720868352/problems/994805480801550336​​ 给出N本书的编号、书名、作者关键词、出版社及出版年份,然后根据某个除编号外的信息来查询所有满足该信息的书的编号,并要求按编号从小到大顺序输出。

2.思路

​map<string,set<int>>​​​分别建立书名、作者、关键词、出版社及出版年份与编号的map映射,
——​​​map<string,set<int>> mpTitle,mpAuthor,mpKey,mpPub,mpYear;​​​。
关键词的逐个提取:每本书都可能有多个关键词,需要将这些关键词分离开——用​​cin​​​来读入单个关键词,然后用​​getchar​​​接收在这个关键词后面的字符:如果是换行符,则说明关键词的输入结束;如果是空格,则继续读入。
——因为​​​cin​​​读入字符串是以空格或者换行为截止标志的,至于书名、作者、出版社及出版年份则是作为整体读入,因此用​​getline​​​来读入整行。
PS:有点奇葩的是在用scanf读取书的ID后要加​​​getchar​​来读掉换行符(虽然scanf是以换行符或空格作为结束标志的,但如果是ID后是空格,此时后面的换行符会被下面的getline读入,导致后面读取错误)。

while(cin>>key){//每次读入单个关键词key
mpKey[key].insert(id);//把id加入到key对应的集合中
c=getchar();//接收关键词key之后的字符
if(c=='\n') break;//如果是换行,说明关键词输入结束
}

3.代码

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<map>
#include <set>
using namespace std;

//key:map<string,set<int>>

//5个map变量分别建立书名、作者、关键字、出版社及出版年份与id的映射关系
map<string,set<int>> mpTitle,mpAuthor,mpKey,mpPub,mpYear;

void query(map<string,set<int>>& mp,string& str){ //在mp中查找str
if(mp.find(str) == mp.end()) printf("Not Found\n"); //找不到
else{ //找到str
for(set<int>::iterator it=mp[str].begin() ; it!=mp[str].end();it++){
printf("%07d\n",*it); //输出str对应的所有id
}
}
}
int main(){
int n,m,id,type;
string title,author,key,pub,year;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&id); //id
char c=getchar(); //接收掉id后面的换行!虽然前面scanf以换行结束
getline(cin,title); //读入书名titile
mpTitle[title].insert(id); //把id加入titile对应的集合中
getline(cin,author);
mpAuthor[author].insert(id); //把id加入author对应的集合中
while(cin >> key){ //每次读入!单个!关键词key
mpKey[key].insert(id); //把id加入key对应的集合中
c=getchar(); //接收关键词key之后的字符
if(c == '\n') break; //如果是换行,说明关键词输入结束
}
getline(cin,pub); //输入出版社pub
mpPub[pub].insert(id); //把id加入pub对应的集合中
getline(cin,year); //输入年份year
mpYear[year].insert(id); //把id加入year对应的集合中
}
string temp; //查询次数
scanf("%d",&m);
for(int i=0;i<m;i++){
scanf("%d: ",&type); //查询类型
//注意读上面的数字后scanf结束
getline(cin,temp);
cout << type <<": "<<temp<<endl; //输出类型和该字符串
if(type==1) query(mpTitle,temp); //查询书名对应的所有id
else if(type == 2) query(mpAuthor,temp); //作者
else if(type == 3) query(mpKey,temp); //关键字
else if(type == 4) query(mpPub,temp); //出版社
else query(mpYear,temp);
}
system("pause");
return 0;
}

4.注意

(1)如果单独把查询操作作为一个函数,则一定要对参数使用引用&,否则最后一组数组会超时。字符串以及map的参数传递速度较慢——如果需要作为函数的参数,最好加上引用。
(2)在scanf或cin输出书的编号id后,必须用​​​getchar​​​接收掉后面的空格,否则​​getline​​会将还将换行读入。


举报

相关推荐

0 条评论