前言
STL中有两种基本基本关联容器:map和set。本文主要介绍map和multimap。
关联容器指通过键来存储和读取元素的容器。
特点:map元素的形式是以键-值(key-value)的形式保存。键是map在访问数据value的索引。
map和multimap的区别是:map的key唯一,而multimap的key不唯一
map
map模板定义
template<class Key,class T,class Comp = less<Key>,class Allocator = allocator<T> > class map
Key是键的数据类型,T是存储值的数据类型,Comp是比较键的函数。
map构造函数
//构造空map
explicit map(const Comp &cmpfn = Comp(), const Allocator &a = Allocator());
//构造包含和ob相同元素的map,也是map的拷贝构造函数
map(const map<Key,T,Comp,Allocator> &ob);
//构造包含start和end指定范围元素的map,比较函数由cmpfn指定
template <class InIter>
map(InIter start,InIter end,const Comp &cmpfn = Comp(),cosnt Allocator &a = Allocator())
map头文件
#include <map>
map重载功能
赋值操作符和比较操作符:==,<,<=,!=,>,>=
map特点
支持双向迭代器,可以通过前向迭代器和反向迭代器访问容器;
不支持随机访问操作;
但支持[]操作符,但和传统用法不同。
pair类型
map存储的元素是pair类型的对象,pair类是以键/值对形式在map中存储元素。
pair类定义在以下头文件中:
#include <utility>
pair模板定义
template<class Ktype,class Vtype>
struct pair{
typedef Ktype first_type; //type of key
typedef Vtype second_type; //type of value
Ktype first; //contains the key
Vtype second; //contains the value
//constructors
pair();
pair(const Ktype &k,const Vtype &v);
template<class A,class B>
pair(const<A,B> &ob)
}
构造pair方法有两种:一种是直接使用pair的构造函数,另一种是使用make_pair方法。
make_pair方法原型
template<class Ktype,class Vtype>
pair<Ktype,Vtype> make_pair(const Ktype &k,const Vtype &v)
make_pair返回pair对象,参数是类型Ktype和Vtype指定的值。
map的迭代器指向的对象也是pair< Key, T >类型。例如:
map< string, int> m;
map< string, int>::iterator p = m.begin()
其中key是p中的first成员,value是p中的second成员。
map成员函数
iterator begin(); const_iterator begin() const | 返回map中指向第一个元素的迭代器 |
void clear() | 删除map中所有元素 |
size_type count(const key_type &k) const | 返回map中键k出现的次数(1或者0) |
bool empty() const | 如果map为空返回true;否则返回false |
iterator end(); const_iterator end() const | 返回指向map尾部的迭代器 |
equal_range(const key_type &k); equal_range(const key_type &k) const | 返回一对迭代器,分别指向map中指定key的上限和下限 |
void erase(iterator i) | 删除由i指定的元素 |
void erase(iterator start,iterator end) | 删除start和end范围内的元素 |
size_type erase(const key_type &k) | 从map中删除由k指定的元素 |
iterator find(const key_type &k); const_iterator find(const key_type &k) const | 返回由k指定的迭代器;如果没有找到会返回map的结束位置 |
allocator_type get_allocator() const | 返回map的适配器 |
iterator insert(iterator i,const value_type &val) | 在i指定的元素后插入值为val的新元素,并返回i的迭代器 |
void insert(InIter start,InIter end) | 插入范围内元素 |
insert(const value_type &val) | 插入val到调用map中。只有当此元素不存在时才允许插入,此函数返回pair对象,其中第一个元素是iterator,第二个元素表明插入操作是否成功,如果插入成功,第二个元素是true,否则是false |
key_compare key_comp() const | 返回比较key的函数对象 |
iterator lower_bound(const key_type &k); const_iterator lower_bound(const key_type &k) const | 返回map中第一个等于或者大于k的元素的迭代器 |
size_type max_size() const | 返回map能保存的最大元素个数 |
reference operator[](const key_type &k) | 返回与键k指定的值的引用。如果元素不存在,则插入 |
reverse_iterator rbegin(); const_reverse_iterator rbegin() const | 返回反向迭代器,起始位置是map尾部 |
reverse_iterator rend(); const_reverse_iterator rend() const | 返回反向迭代器,起始位置是map头部 |
size_type size() const | 返回当前map中含有的元素个数 |
void swap(map &ob) | 用ob和当前map交换之间的元素 |
iterator upper_bound(const key_type &k); const_iterator upper_bound(const key_type &k) const | 返回map中键大于k的第一个元素的迭代器 |
value_compare value_comp() const | 返回比较值的函数对象 |
代码样例
//example 1
map<char,int> m;
int i = 0;
//put pairs into map
for (i=0;i<26;i++)
{
//三种插入元素方式
//m.insert(pair<char,int>('A' + i, 65 + i));
//m.insert(make_pair((char)('A' + i), 65 + i));
m['A' + i] = 65 + i;
}
char ch;
cout<<"Enter key: ";
cin>>ch;
map<char,int>::iterator p;
//find value given key
p = m.find(ch);
cout<<"Its ASCII value is "<<m[ch];
if (p!=m.end())
{
cout<<"Its ASCII value is "<<p->second;
}else{
cout<<"Key not in map.\n";
}
class name{
string str;
public:
name(){ str = ""; }
name(string n){ str = n; }
string get(){ return str; }
};
//must define less than relative to name objects
bool operator<(name a,name b)
{
return a.get() < b.get();
}
//this is the value class
class phoneNum{
string str;
public:
phoneNum(){ str = "";}
phoneNum(string n){ str = n;}
string get(){ return str; }
};
int _tmain(int argc, _TCHAR* argv[])
{
map<name,phoneNum> m;
//put names and numbers into map
m.insert(pair<name,phoneNum>(name("Tom"),phoneNum("555-4533")));
m.insert(pair<name,phoneNum>(name("Chris"),phoneNum("555-9678")));
m.insert(pair<name,phoneNum>(name("John"),phoneNum("555-8195")));
m.insert(pair<name,phoneNum>(name("Rachel"),phoneNum("555-0809")));
//given a name, find number
string str;
cout<<"Enter name: ";
cin>>str;
map<name,phoneNum>::iterator p;
p = m.find(name(str));
if (p!=m.end())
{
cout<<"Phone number: "<<p->second.get();
}
else
{
cout<<"Name not in directory.\n";
}
return 0;
}
multimap
特点:一对多的关系,即一个key可以对应多个value
multimap模板定义
template <class Key,class T,class Comp = less<Key>,class Allocator = allocator<T> > class multimap
Key键的类型
T存储值的类型
Comp比较key的函数
构造函数
//构造空multimap函数
explicit multimap(const Comp &cmpfn = Comp(),const Allocator &a = Allocator())
//multimap的拷贝构造函数
multimap(const multimap<Key,T,Comp,Allocator> &ob)
//multimap由start和end指定元素的构造函数
template<class InIter>
multimap(InIter start,InIter end,const Comp &cmpfn = Comp(),const Allocator &a = Allocator())
头文件
#include <map>
代码样例
multimap<string,string> names;
string n;
names.insert(pair<string,string>("Jones","Fred"));
names.insert(pair<string,string>("Jones","Alice"));
names.insert(pair<string,string>("Smith","Tom"));
names.insert(pair<string,string>("Smith","Alicia"));
names.insert(pair<string,string>("Smith","Jon"));
names.insert(pair<string,string>("Doe","Harvey"));
names.insert(pair<string,string>("Doe","Wilma"));
names.insert(pair<string,string>("Doe","Rachel"));
names.insert(pair<string,string>("Johnson","J.T."));
multimap<string,string>::iterator p;
cout<<"Enter last name: ";
cin>>n;
//get iterator to first occurrence
p = names.find(n);
if (p!= names.end())
{
//found a name
do
{
cout<<n<<", "<<p->second;
cout<<endl;
p++;
} while (p !=names.upper_bound(n));
}else{
cout<<"Name not found.\n";
}