map和set
c++98支持的是单参数的隐式类型转换,而c++11支持多参数的隐式类型转换;
1.map和set的使用
1.1set
set实现key值不允许修改,是将iterator转变成const_iterator;可以对同一个类型typedef成两个不同的自定义标识符。即set没有设置普通迭代器;
set的底层是红黑树,使用仿函数比较大小。关联式容器。
set可以实现比较记录重复次数但是需要重载仿函数,实现key_value只需要set内部实现的是一个结构体。
count和equal_range在set容器里面一样不大,而在multiset才有意义。
template < class T, // set::key_type/value_typeclass Compare = less<T>, // set::key_compare/value_compareclass Alloc = allocator<T> // set::allocator_type> class set;
//1.构造
empty (1) explicit set (const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
range (2) template <class InputIterator>set (InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
copy (3) set (const set& x);
//2.迭代器
//和一起的容器一样,迭代器底层走的是一个中序遍历,还可以去重。
//3.insert
iterator insert (iterator position, const value_type& val);//某个迭代器位置进行插入
//4.erase
void erase (iterator position);//配合find使用,使用find找到迭代器位置。
size_type erase (const value_type& val);//根据值来进行删除。其实就是find和erase的复用,但是会断言。
//5.find
template <class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val);//暴力查找会查找O(N)次
iterator find (const value_type& val) const;//因为树的左右两边是平衡的,会根据大小进行比较,最多访问高度次lg(N)次,建议优先使用它。
//6.key/value的仿函数
key_compare key_comp() const;
value_compare value_comp() const;
//7.count
size_type count (const value_type& val) const;//返回这个值出现的次数,在set中存在返回的就是1,不存在返回的就是零。
//8.找边界
//常用在erase使用区间删除
iterator lower_bound (const value_type& val) const;//返回的迭代器位置是大于等于这个值
iterator upper_bound (const value_type& val) const;//由于区间一般是左闭右开,所以返回的迭代器位置一般是这个值的下一位。即删除找左闭右闭,查找找左闭右开
//9.找区间
pair<iterator,iterator> equal_range (const value_type& val) const;
1.2multiset(Multiple-key set)
支持键值冗余的multiset容器,相等的值插入在左边和右边都可以。
//1.count
size_type count (const value_type& val) const;//返回val的个数
//2.equal_range
pair<iterator,iterator> equal_range (const value_type& val) const;//由于set容器是一个有序的红黑树,所以大小相同的值的是一段连续的区间范围,可以用pair结构来接收迭代区间的lower和upper。返回大于val数的[val+,val+)
//3.find
//相较于set的find,由于有了数据冗余,所以返回值返回的是中序遍历的第一个val的iterator
1.3map
使用map来完成括号匹配问题,而且初始化用initializer_list更加方便。
键值唯一,value可重复;map内存放的是pair对象;key必须支持比较大小;如果不支持比较大小可以自己写一个仿函数来实现,因为仿函数比较使用的就是key;
template < class Key, // map::key_typeclass T, // map::mapped_typeclass Compare = less<Key>, // map::key_compare,只有key参与比较class Alloc = allocator<pair<const Key,T> > // map::allocator_type> class map;//相较于set多了一个模板参数,用来设置value
//1.insert
pair<iterator,bool> insert (const value_type& val);//1.value_type是一个pair<const key_type,mapped_type>,即key只读不允许写入,而value可读写;2.可以使用make_pair函数模板来实现传入参数val或者使用隐式类型转换;3.设置pair的原因是c++不支持返回多个参数,但是可以返回一个结构,如:解引用运算符重载返回的就是一个结构;4.key相同但是value不相同,也不会插入不会覆盖,值比较key,不关心value;5.返回值插入成功返回true,要插入的key值存在则是false
//2.erase
void erase (iterator position);
size_type erase (const key_type& k);
//3.operator[]
mapped_type& operator[] (const key_type& k);//特点是通过key来返回value;
//对于不存在的key值会创建并用匿名对象来初始化pair,已经存在的key值会修改value值;
//底层实现就是return (*((this->insert(make_pair(k,mapped_type()))).first)).second,即使用的是insert的返回值中的迭代器位置的value。
//1.可以使用[]来实现统计出现的次数;2.可以实现插入加修改;
1.4multimap
支持键值冗余的multimap容器,value和map一样。
1.相较于map没有提供[],因为键值不是唯一的。
2.insert返回的是迭代器不是pair,因为插入一定成功;
3.哈希的效率可以达到O1;
1.5pair
template <class T1, class T2>
struct pair {typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1()), second(T2()) {}pair(const T1& a, const T2& b) : first(a), second(b) {}
}