map与multimap基本性能
map和multimap属于关联式容器,它们将key/value pair当作元素进行管理,会根据key的排序准则自动为元素排序。和其他所有关联式容器一样,map/multimap通常以平衡二叉树完成。map/multimap的特点在于其元素是key/value pair类型,其次,map可作为关联式数组来运用。
受自动排序的影响,通过key值来查找元素会有很好的效率,但你不能直接改变元素的key,这会破坏正确次序。要想修改元素的key,你必须先移除拥有该key的元素,然后插入新的key/value的元素。
map与multimap使用须知
1.头文件
#include<map>
2.class template
namespace std { template <typename Key, typename T, typename Compare = less<key>, typename Allocator = allocator<pair<const key, T>>>
class map; template <typename Key, typename T, typename Compare = less<key>, typename Allocator = allocator<pair<const key, T>>>
class multimap; }
第一个template实参将成为元素的key类型,第二个template实参将成为元素的value类型。
值得注意的是,map和multimap的元素类型key和T必须满足一下条件:
1.key和T都必须是copyable或movable(可复制和搬移的)。
2.对指定的排序准则而言,key必须是comparable(可比较的)。
3.元素类型是一个pair<const key,T>。
4.第三个实参template可有可无,用来定义排序准则。排序准则必须定义为strict weak ordering。不传入排序准则的情况下,默认使用less<>准则。
默认情况下,multimap对于等价key的元素的排序保持其相对次序不变。
map与multimap操作函数
1.创建、复制和销毁
map c //default构造函数,建立一个空的map/multimap,不含任何元素
map c(op) //建立一个空的map/multimap,以op为排序准则
map c(c2) //copy构造函数,建立一份相同类型的map/multimap的拷贝
map c=c2 //copy构造函数,建立一份相同类型的map/multimap的拷贝
map c(beg,end) //以区间[beg,end)元素为初值,建立一个map/multimap
map c(beg,end,op) //以区间[beg,end)元素为初值,并以op为排序准则,建立一个map/multimap
c.~map() //销毁所有元素,释放内存
map<key,val> //一个map,以less<>为排序准则
map<key,val,op> //一个map,以op为排序准则
multimap<key,val> //一个multimap,以less<>为排序准则
multimap<key,val,op> //一个multimap,以op为排序准则
2.非更易型操作
c.key_comp() //返回key的比较准则
c.value_comp() //返回value的比较准则
c.empty() //返回是否容器为空
c.size() //返回目前元素个数
c.max_size() //返回元素个数之最大可能
3.特殊查找动作
c.count(val) //返回“key为val”的元素个数
c.find(val) //返回”key为val”的第一个元素,找不到就返回end()
c.lower_bound(val) //返回“key为val”之元素的第一个可安插位置,也就是“key>=val”的第一个元素位置
c.upper_bound(val) //返回“key为val”之元素的最后一个可安插位置,也就是“key>val”的第一个元素位置
c.equal_range(val) //返回“key为val”之元素的第一个可安插位置和最后一个可安插位置,也就是“key==val”的元素区间,返回值为pair型
4.迭代器函数和元素访问
map/multimap不支持元素直接访问,唯一的例外map提供at()以及subscrip(下标)操作符来直接访问元素。通常情况下,元素的访问时经由range-based-for循环或迭代器进行
c.begin(); //返回一个bidirectional iterator指向第一元素
c.end(); //返回一个bidirectional iterator指向最末元素的下一位置
c.rbegin(); //返回一个reverse iterator指向反向迭代的第一元素
c.rend(); //返回一个reverse iterator指向反向迭代的最末元素的下一位置
5.元素的安插和移除
c.insert(val) //安插一个val拷贝,返回新元素位置,无论是否成功
c.insert(pos,val) //安插一个val拷贝,返回新元素位置,pos是一个查找起点提示
c.insert(beg,end) //将区间[beg,end)内所有元素拷贝安插
c.emplace(val) //安插一个初值为val的元素,返回新元素的位置,无论是否成功
c.erase(val) //移除与“val”相等的所有元素,返回被移除的元素个数
c.erase(pos) //移除iterator位置pos上的元素,无返回值
c.erase(beg,end) //移除区间[beg,end)内的所有元素,无返回值
c.clear() //移除所有元素,将容器清空
因为将map视为关联数组的操作虽然在代码上显得方便简介,但因其需要先default构造函数将value初始化,会获得比常规map操作低的效能,所以在此不做细说