Map中根据元素的key自动对元素进行排序。这样一来,根据已知的key搜寻某个元素时,能够获得很好的性能,而根据已知的value搜寻元素时,性能就很糟糕。自动排序,使得map中不可以直接改变元素的key的值,要改变元素的key,必须先移除拥有该key的元素。
map的生成、复制
map c; 产生一个空的map,不含任何元素。
map c(op) 以op为排序准则,产生一个空的map。
map c1(c2) 产生一个map的副本,所有元素均被复制。
map c(beg,end) 以区间[beg,end]内的元素产生一个map。
map c(beg,end,op) 以op为排序准则,利用[beg,end]内的元素生成一个map。
map的赋值操作:
c1 = c2 将c2中的元素赋值给c1。
c1.swap(c2)、swap(c1,c2) 将c1和c2的元素互换。
这三个操作必须要求型别相同,即c1和c2的排序准则和allocator必须相同。尽管比较准则本身可能不同,但其型别必须相同。一个型别相同但比较准备不同的例子
map的非变动操作:
c.size() 返回容器的size
c.empty() 判断容器大小是否为0
c.max_size() 返回克可容纳的最大元素数量
c1 == c2 c1 != c2 c1 < c2 c1 > c2 c1 <= c2 c1 >= c2
元素的比较动作只能用于型别相同的容器。
特殊的搜寻动作:
count(key) 返回等于key的元素个数
find(key) 返回键值等于key的第一个元素,找不到返回end()
lower_bound(key) 返回“键值为key”之元素的第一个可安插位置,也就是“键值>=key"的第一个元素位置
upper_bound(key) 返回“键值为key”之元素的最后一个可安插位置,也就是“键值>key"的第一个元素位置
equal_bound(key) 返回”键值为key“之元素的第一个可安插位置和最后一个可安插位置。也就是”键值==key“的元素区间。
map迭代器操作:
begin()、end()、rbegin()、rend()
迭代器是双向迭代器,map中所有元素的key都被视为常数,因此元素的实质型别为pair<const key,T>。这个限制可以确保因为变更元素的key而破坏已排好的元素次序。所以不能针对map调用变动型算法,PS:不能调用remove方法。
NOTE:关联式容器和更易型算法
更易型算法(remove、sort、修改元素的算法)用在关联容器身上会出问题。
原因:如果更易型算法用于关联式容器身上,会改变某位置的值,进而破坏已序特性,那就推翻了关联式容器的基本原则:容器内的元素总是根据某个排序准则自动排序。因此,为了保证这个原则,关联式容器的所有迭代器都被声明为指向常量。
map元素的安插和移除操作:
c.insert(elem) 安插一份elem副本,返回新元素位置(不论是否成功)
c.insert(pos,elem) 安插一份elem副本,返回新元素位置(pos是个提示,指出安插操作的搜寻起点,如果提示恰当,克大大加快速度)。
c.insert(beg,end) 将区间[beg,end]中的所有元素安插到c。
c.earse(elem) 移除value与elem相等的所有元素,返回被移除的元素个数。
c.earse(pos) 移除迭代器pos所指位置上的元素,无返回值
c.earse(beg,end) 移除区间[beg,end]内的所有元素,无返回值
安插一个key/value时,你要记住,map内,key被视为常数。你要不就提供正确的型别,要不就提供隐式或者显示型别转换。三种安插:
std::map<std::string,float> coll;
1、coll.insert(std::map<std::string,float>::value_type("otto",22.3));
2、coll.insert(std::pair<const std::string,float>("otto",22.3));必须加const
3、coll.insert(std::make_pair("otto",22.3));
map中移除元素时用for循环直接删除
for(pos = coll.begin();pos != coll.end();++pos)
{
if(pos->second == value)
coll.erase(pos);
}
对pos所指元素执行erase操作,会使pos成为一个失效的迭代器,再执行++pos,会出项runtime error。
下面是正确的做法:
for(pos = coll.begin();pos != coll.end();)
{
if(pos->second == value)
coll.erase(pos++);
else
++pos;
}