1.概述
map是一种关联式容器(associative container),键值对<key, value>序列。它提供基于key的快速检索能力,在一个map中key值是唯一的。map提供双向迭代器,即有从前往后的(iterator),也有从后往前的(reverse_iterator)。
泛型原型:template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
第一个参数Key是关键字类型 ;
第二个参数T是值类型 ;
第三个参数Compare是比较函数(仿函数);
第四个参数是内存配置对象。
2. 基本操作
.insert( )插入<key, value>对。
.find(key)查找map中key,若能查找到,返回iterator;若没找到,返回map::end。
.begin( ), .end( )表示迭代器的开始与结束。
.earse( )从map中删除<key, value>对。
.clear()相当于 .erase(.begin( ), .end( ));
3. Referrence
[1] cplusplus,http://www.cplusplus.com/reference/map/map/
[2] 吴秦,STL之Map。
[3] wuqifu,C++ STL map::insert小结。
4.问题
4.1 POJ 1002
题目大意:根据映射规则,求重复的电话号码。
用map<string,int>记录每种电话号码的个数。
源代码:
1002 | Accepted | 5192K | 1329MS | C++ | 829B | 2013-09-25 20:50:49 |
#include<iostream>
#include<map>
#include<string>
using namespace std;
char letter[26]={'2','2','2','3','3','3','4','4','4','5','5','5','6','6','6','7',' ','7','7','8','8','8','9','9','9',' '};
map<string,int>num;
void count(string str)
{
int i;
string temp="";
for(i=0;i<=str.length();i++)
{
if(isdigit(str[i]))
temp+=str[i];
else if(isupper(str[i]))
temp+=letter[str[i]-'A'];
}
temp.insert(3,"-");
num[temp]++;
}
int main()
{
int N;
string str;
bool duplicate=false;
scanf("%d",&N);
while (N--)
{
cin>>str;
count(str);
}
map<string,int>::iterator it;
for(it=num.begin();it!=num.end();it++)
if(it->second>=2)
{
cout<<it->first<<" "<<it->second<<endl;
duplicate=true;
}
if(!duplicate)
printf("No duplicates. \n");
return 0;
}
4. 2 POJ 2491
题目大意:给出每一步的起点和终点,求整个路线图。
用两个map,一个(step)记录起点和终点,一个(num)记录点出现的次数。出现一次的点,可能是路线图的开始点,也可能是路线图的结束点;如果点有后继点(即step[ ]不为空),说明该点是起点。
源代码;
2491 | Accepted | 320K | 329MS | C++ | 697B | 2013-09-26 10:54:13 |
#include<iostream>
#include<map>
#include<string>
using namespace std;
map<string,string>step;
map<string,int>num;
int main()
{
int i,j,scenarios,S;
string str1,str2,start;
map<string,int>::iterator it;
cin>>scenarios;
for(i=1;i<=scenarios;i++)
{
cin>>S;
step.clear(); //clear
num.clear();
for(j=1;j<S;j++)
{
cin>>str1>>str2;
step[str1]=str2;
num[str1]++;
num[str2]++;
}
for(it=num.begin();it!=num.end();it++)
if(it->second==1&&step[it->first]!="")
{
start=it->first;
break;
}
cout<<"Scenario #"<<i<<":\n";
while (start!="")
{
cout<<start<<endl;
start=step[start];
}
cout<<endl;
}
return 0;
}
4.3 POJ 2643
题目大意:统计选举获胜者,并输出其所在党派。
cin.ignore( )处理输入的n和m之后回车符;getline( )可读取空格字符,遇到回车字符停止读取。
源代码:
2643 | Accepted | 264K | 16MS | C++ | 792B | 2013-09-26 16:01:51 |
#include<iostream>
#include<map>
#include<string>
using namespace std;
map<string,string>party;
map<string,int>num;
int main()
{
int i,n,m;
string str1,str2,winner;
cin>>n;
cin.ignore();
for(i=1;i<=n;i++)
{
getline(cin,str1);
getline(cin,str2);
party[str1]=str2;
}
cin>>m;
cin.ignore();
for(i=1;i<=m;i++)
{
getline(cin,str1);
num[str1]++;
}
map<string,int>::iterator it;
it=num.begin();
winner=it->first;
for(;it!=num.end();it++)
{
if(it->second>num[winner])
winner=it->first;
}
bool tie=false;
for(it=num.begin();it!=num.end();it++)
{
if(it->second==num[winner]&&it->first!=winner)
{
tie=true;
break;
}
}
if(tie)
cout<<"tie\n";
else
cout<<party[winner]<<endl;
return 0;
}
4.4 POJ 2503
题目大意:将an English word翻译成a foreign language word。
输出很坑,参考这里写的,顺便熟悉了一下ungetc函数的用法。用了while(1) { ... }循环做输出,Output Limit Exceeded了一次。
源代码:
2503 | Accepted | 9620K | 1204MS | C++ | 450B | 2013-09-27 17:15:03 |
#include<iostream>
#include<map>
#include<string>
using namespace std;
map<string,string>dictionary;
int main()
{
string str1,str2;
char ch;
while(1)
{
cin>>str1>>str2;
dictionary[str2]=str1;
getchar();
ch=getchar();
if(ch=='\n')
break;
ungetc(ch,stdin);
}
while(cin>>str1)
{
if(dictionary.find(str1)!=dictionary.end())
cout<<dictionary[str1]<<endl;
else
cout<<"eh\n";
}
return 0;
}