Description
输入n个字符串对(str1,str2),再输入k个查询字符串str,从字符串对中查找查询字符串,即如果str=str2,则输出str1,如果查询不到则输出"eh"(不包含引号)。输入保证所有字符串对的str2不相同,字符串只含有字母和数字,长度小于20!
Input
输入包含多组数据,直到文件结尾。
每组数据第一行包含一个整数n(0≤n≤10^5)。接下来n行,每行描述一个字符串对。
接下来包含一个整数m(0≤m≤10^5)。接下来m行,每行描述一个查询字符串。
见样例
Output
输出每个查询的结果。
Sample Input
5
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay
3
atcay
ittenkay
oopslay
Sample Output
cat
eh
loops
HINT
用STL的map容易实现
AC代码
#include <iostream>
#include <map>
#include <stdio.h>
using namespace std;
map<string,string>s;
int main()
{
int n;
char a[21],b[21];
char c[21];
while(~scanf("%d",&n))
{
s.clear();//千万别忘记清空;
for(int i=0;i<n;i++)
{
cin>>a>>b;
s[b]=a;
}
int k;
cin>>k;
for(int j=0;j<k;j++)
{
scanf("%s",c);
if(s.count(c))
cout<<s[c]<<endl;
else
cout<<"eh"<<endl;
}
}
return 0;
}
对此代码作如下解释:
一、map容器的解读
map是set中的一种,因此map也是集合,而且是<键,值>对的集合,其中,a是键,b是值,map里的元素的类型是pair<a,b>
,其中它的意思是从类型a到类型b的映射,在map容器中,一个b可以对应多个a,但一个a只能对应一个b。
二、用数组方式插入数据
https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html其中讲述了三种插入的方法,在这里具体讲解数组插入数据的方法。
map[下标]=a,map中的下标只对应键值对的first值,而等号右边的a则为second中的值。
举例说明:s[b]=a就是把b在s中的映射设为a,b是first,a实际上是second,如果在s里有first为b的pair,就把它的second改为a,如果没有,就插入一个pair(a,b)。
在做s[b]=a操作后,s[b]有值,但是s[a]没有值,因为first中没有a;
例如:
int main()
{
map<string, string> mapStudent;
map<string,string>::iterator iter;
char a[33],b[33];
cin>>a>>b;
string c;
mapStudent[b] = a;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
cout<<iter->first<<" "<<iter->second<<endl;
}
cout<<mapStudent[a]<<endl;
cout<<mapStudent[b]<<endl;
cin>>c;
// cout<<mapStudent.count(a)<<endl;
// if(mapStudent.count(a))
// cout<<mapStudent[a]<<endl;
mapStudent[a] = c;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
cout<<iter->first<<" "<<iter->second<<endl;
}
cout<<mapStudent[a]<<endl;
cout<<mapStudent[b]<<endl;
}
mapStudent[b]的时候实际上输出的是a,但是如果要输出b的话,则要通过iter->first来进行输出b。
三、map中的查询
(1)map的查询不是直接就能查到的,而是要按照规则一个一个往下搜,是按照二叉树的形式,找到它应该放的位置然后插进去。
(2)count:s.count(a),找的是与a对应的值(相对应的意思是 ==a),而且是在first中找,不在second中找.
四、对于本题做如下说明
(1)让b映射a,如果输入的c和first中的b相同的话,那么输出b所对应的映射,为什么要把b作为first呢?是因为count在搜寻的时候,只能在first中搜寻。
(2)这个题总是显示输出超限,到底是哪里导致输出超限呢?
第一 string:string读入的比较慢,输出不会耗费太多的时间,char[]比较快
第二 cin:读入数据的时候比scanf慢很多
第三 cout:输出数据的时候比printf慢很多
(3)对于string来说,只能用cin读入,只能通过cout输出,不能用scanf读入,printf输出。
(4)map中是无法存char[]类型的,所以map里要用string,但是它会自动转化类型,转化为它本身可以读入的类型即string,所以
这里在printf的时候出错,因为string是无法通过printf实现输出的。
(5)对于判断EOF结束输出的问题,while(cin>>n)
对于cin来说就是已经代表了EOF的意思,但是对于scanf来说,while(~scanf("%d",&n))
或者while(scanf("%d",&n)!=EOF)
或者while(scanf("%d",&n)==1)
;
(6)对于char*类,scanf的时候不用&符号
五、基本操作函数
(一)map的基本操作函数:
(1)差不多对于set适用的函数对于map也适用,但是一般都是对于first的操作,而erase()则是对于first和second两者的操作。
(2)map里是没有push_back的函数的,vector和string中有,stack里面有push,不是push_back,push_front貌似被去掉了,因为效率太低。
(3)count:s.count(a),找的是与a对应的值(相对应的意思是 ==a),而且是在first中找,不在second中找.
(4)erase:消除了first和second中的值。
(二) C++ maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数