map的特性是,所有的元素都会根据元素的键值自动被排序,map的所有元素都是pair,同时拥有实值(value)和键值(key)。pair的第一个元素
被视为键值,第二个元素被视为实值。map不允许两个元素有相同的键值。
//下面给出<stl_pair.h>中的pair的定义
template<class T1,class T2>
struct pair{
typedef T1 first_type;
typedef T2 second_type;
T1 first;//注意,它是public
T2 second;//注意,它是public
pair():first(T1()),second(T2()){}
pair(const T1&a,const T2&b):first(a),second(b){}
};
不可以通过迭代器修改map的键值,因为涉及map元素的排列规则,但是可以修改map的实值
所以标准的STL map以RB_tree作为底层机制
又由于map所开放的各种操作接口,RB-tree也都提供了 所以几乎所有的map操作行为,都只是转调用RB-tree的操作行为而已。
//下面是map的源码实现
template <class Key,class T,class Compare=less<key>,//缺省采用递增排序
class Alloc=alloc>
class map{
public:
//typedefs
typedef Key key_type;//键值型别
typedef T data_type;//数据(实值)型别
typedef T mapped_type;
typedef pair<const Key,T>value_type;//元素型别(键值/实值)
typedef Compare key_compare;//键值比较函数
//以下定义一个functor,其作用就是调用“元素比较函数”
class value_compare
:public binary_function<value_type,value_type,bool>{
friend class map<Key,T,Compare,Alloc>;
protected:
Compare comp;
value_compare(Compare c):comp(x){}
public:
bool operator()(const value_type&x,const value_type&y)const{
return comp(x.first,y.first);
}
};
private:
//以下定义表述型别(representation type).以map元素型别(一个pair)
//的第一个型别,作为RB_tree结点的键值型别
typedef rb_tree<Key_type,value_type,select1st<value_type>,key_compare,Alloc>rep_type;
rep_type t;//以红黑树(RB_tree)表现map
public:
ypedef typename rep_type::pointer pointer;
typedef typename rep_type::const_pointer const_pointer;
typedef typename rep_type::reference reference;
typedef typename rep_type::const_reference const_reference;
typedef typename rep_type::iterator iterator;
//注意上一行map不像set一样将iterator定义RB-tree的
//const_iterator,因为它允许用户通过迭代器修改元素的实值(value)
typedef typename rep_type::const_iterator const_iterator;
typedef typename rep_type::reverse_iterator reverse_iterator;
typedef typename rep_type::reverse_iterator reverse_iterator;
typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
typedef typename rep_type::size_type size_type;
typedef typename rep_type::difference_type difference_type;
//allocation/deallocation
//注意,map一定使用底层RB-tree的insert-unique(),而非insert_equal()
//multimap才使用insert_equal()
//因为map不允许相同的键值存在,multimap才允许相同的键值存在
map():t(Compare()){}
explicit map(const Compare &comp):t(comp){}
template<class InputIterator>
map(InputIterator first,InputIterator last)
:t(Compare()){t.insert_unique(first,last);}
template <class InputIterator>
map(InputIterator first,InputIterator last,const Compare &comp)
:t(comp){t.insert_unique(first,last);}
//构造函数
map(const map<Key,T,Compare,Alloc>&x):t(x.t){}
map<key,T,Compare,Alloc>&operator==(const map<key,T,Compare,Alloc>&x){
t=x.t;
return *this;
}
//accessors:
//以下所有的map操作行为,RB_tree都已经提供
key_compare key_comp()const{return t,key_comp();}
value_compare value_comp()const{return value_compare(t.key_comp());}
iterator begin(){reuturn t.begin();}
const_iterator begin() const{return t.begin();}
iterator end(){return t.end();}
const_iterator end()const{return t.end();}
reverse_iterator rbegin(){return t.end();}
const_reverse_iterator rbegin() const{return t.rbegin();}
reverse_iterator rend(){return t.end();}
const_reverse_iterator rend() const{return r.rend();}
bool empty()const{return t.empty();}
size_type size()const{return t.size();}
size_type max_size() const{return t.max_size();}
//注意 以下是下标操作符
T& operator[](const key_type& k){
return (*((insert(value_type(k,T()))).first)).second;
}
void swap(map<key,T,Compare,Alloc>& x){t.swap(x.t);}
//insert/erase
//注意以下insert操作并返回的型别
pair<iterator,bool>insert(const value_type&x){
return t.insert_unqiue(x);
}
iterator insert(iterator position,const value_type &x){
return t.insert_unique(position,x);
}
template<class InputIterator>
void insert(InputIterator first,InputIterator last){
t.insert_unique(first,last);
}
void erase(iterator position){t.erase(position);}
size_type erase(const key_type&x){return t.erase(x);}
void erase(iterator first,iterator last){t.erase(first,last);}
void clear(){t.clear();}
//map operations:
iterator find(const key_type &x){return t.find(x);}
const_iterator find(const key_type&x)const{return t.find(x);}
size_type count(const key_type&x)const {return count(x);}
iterator lower_bound(const key_type&x){return t.lower_bound(x);}
const_iterator lower_bound(const key_type &x)const{
return t.lower_bound(x);
}
iterator upper_bound(const key_type &x){return t.upper_bound(x);}
const_iterator upper_bound(const key_type&x)const{
return t.upper_bound(x);
}
pair<iterator,iterator>equal_range(const key_type&x){
return t.equal_range(x);
}
pair<const_iterator,const_iterator>equal_range(const key_type&x)const{
return t.equal_range(x);
}
friend bool operator==__STL_NULL_TMPL_ARGS(const map&,const map&);
friend bool operator<__STL_NULL_TMPL_ARGS(const map&,const map&);
};
template <class Key,class Compare,class Alloc>
inline bool operator==(const map<key,T,Compare,Alloc>&x,const map<Key,T,Compare,Alloc>&y){
return x.t==y.t;
}
template <class Key,class T,class Compare,class Alloc>
inline bool operator<(const map<key,T,Compare,Alloc>&x,const map<key,T,Compare,Alloc>&y){
return x.t<y.t;
}
下面给出一个实例
#include<map>
#include<iostream>
#include<string>
using namespace std;
int main(){
map<string,int>simap;//以string为键值,以int为实值
simap[string ("jjhou")]=1;
simap[string ("jerry")]=2;
simap[string ("jason")]=3;
simap[string ("jimmy")]=4;
pair<string,int>value(string("david"),5);
simap.insert(value);
map<string,int>::iterator simap_iter=simap.begin();
for(;simap_iter!=simap.end();++simap_iter)
cout<<simap_iter->first<<' '
<<simap_iter->second<<endl;
int number=simap[string("jjhou")];
cout<<number<<endl;
map<string,int>::iterator ite1;
//面对关联式容器,应该使用其所提供的find()函数来搜索元素,会比
//使用STL算法的find()更有效率,因为STL算法的find()只有循序搜寻
ite1=simap.find(string("mchen"));
if(ite1==simap.end())
cout<<"mchen not found"<<endl;
ite1=simap.find(string("jerry"));
if(ite1!=simap.end())
cout<<"jerry found"<<endl;
ite1->second=9;//可以通过迭代器修改value值
int number2=simap[string("jerry")];
cout<<number2<<endl;
return 0;
}
``