STL教程之容器--(3)关联式容器(set/multiset、map/multimap)

在这里插入图片描述

关联式容器其实就是关联数组概念的推广,依据选定的排序准则,自动为其元素排序。通常关联式容器是由二叉树做出来的,每个元素都有一个父节点和两个子节点,左子树的所有元素都比自己小,右子树的所有元素都比自己大。关联式容器的差别在于元素的类型以及处理重复元素的方式。关联式容器有一个很大的优点就是提供了对元素的快速访问,但是却不能实现任意位置的操作。

1、set/multiset类模板

集合是一种随机存取的容器,能按顺序存储一组值,其关键词和数据文件时同一个值,集合对象可以使程序按照次序来存储一组数值,在一个集合中的元素既作为被存储的数据又作为数据的关键值。集合的本质就是一个有序的排列,集合声明在头文件< set>内,multiset与set除了set元素中的值必须具有唯一值,即不能包含重复的元素,但是multiset可以包含重复的元素外,其他完全一样,set/multiset的迭代器是双向迭代器,本文以set为例介绍其用法。set的声明格式如下:

template < class Key,class Traits=less< Key>,class Allocator< Key> >
class set;

其中参数Key是存储在集合中元素的类型,参数Traits用于实现集合内部排序的仿函数,默认为less< Key>,即升序,参数Allocator为内存配置器,负责内存的分配和销毁。

(1)构造函数

 (1) explicit set(const Traits& _Comp);          
  (2)explicit set(const Traits& _Comp,const Allocator& _All);
  (3)set(const _set& _Right);
  (4)tmplate< class InputIterator> set(InputIterator first,InputIterator last);
  (5)tmplate< class InputIterator> set(InputIterator first,InputIterator last,const Traits& _Comp);
  (6)tmplate< class InputIterator> set(InputIterator first,InputIterator last,const Traits& _Comp,const Allocator& _All);

上面第一种方法最简单,定义一个空对象(容器),参数包含了一个二元谓词(重载()运算符),用于容器的内部排序。第二种形式出包含一个谓词外,还加入了内存配置器参数。第三种形式用已有的set来初始化新的set,第四种形式用first和last指定范围来初始化新的set。第五种形式比第四种形式多了参数_Comp,从而可以自定义排序规则。第六种形式在第五种形式的基础上增加了内存配置器。

(2)容量、搜寻、统计函数

bool empty( )const;                            /* 判断set是否为空 */

size_type size( )const;                      /* 获取set的长度 */

size_type max_size( )const;             /* 获取set的最大长度 */

size_type count( const Key& _Key )const;   /* 获取元素_Key的个数*/

iterator find(const Key& _Key)const;/* 返回键值为_Key的元素的位置,类型为迭代器 */
const iterator lower_bound(const Key& _Key)const;/* 返回键值大于等于_Key的第一个元素的迭代器位置 */

const iterator upper_bound(const Key& _Key)const;/* 返回键值大于_Key的第一个元素的迭代器位置 */

pair< iterator,iterator>equal_range(const Key& _Key)const;/* 函数返回类型为迭代器对(pair),该迭代器对的两个迭代器分别指向集合中元素键值大于等于_Key的第一个元素的迭代器位置(first)和集合中键值大于_Key的第一个元素的迭代器位置(second) */
/*例如:std::pair<std::set<int>::iterator,std::set<int>::iterator> p; */

(3)迭代器及赋值函数

void swap(set& str);/* 交换两set的元素 */
const_iterator begin();/* 返回set的首元素 */
const_iterator end();/* 返回set的尾元素 */
const_reverse_iterator rbegin();/* 返回set的尾元素 */
const_reverse_iterator rend();/* 返回set的首元素 */

(4)插入删除函数
不能对空集合进行删除操作,所以在删除函数前,需要有容器容量判断。

pair<iterator,bool>insert(const value_type& x);/* 返回值为pair类型的迭代器指针first代表插入元素的位置,第二个为bool类型,表示插入是否成功 */

iterator insert(iterator it,const value_type& x);/* 在集合it位置插入元素x,实际上不生效,会自动排序 */

void insert(const value_type& first,const value_type& last);/* 插入迭代器first到last之间的元素到集合中,打乱,重新排序 */

iterator erase(iterator it);/* 清除元素it */
iterator erase(iterator first,iterator last);/* 清除迭代器first到last之间的元素 */
size_type erase(const key& key);/* 清除关键值为key的元素 */

void clear();/* 清空set集合 */

(5)元素比较函数

key_compare key_comp()const;           /* 返回该set的键值比较函数 */
value_compare value_comp()const;    /* 返回该set的实值比较函数 */

2、map/multimap类模板

容器map是键-值对的集合,键是独一无二的,可使用键作为下标获取对应的值,map/maomultimap容器的对象以数据的形式存放在二叉树中,容器map与multimap基本是一样的,除了multimap允许重复元素,map不允许外,map/multimap的迭代器是双向迭代器,下面以map为例,详细讲解该模板的使用。
map声明在< map>内,模板为:

template< class Key,class T,class Compare=less< Key>,class Allocator=allocator<pair< const key,T>>>
class map;

第一个参数为容器的key,第二个template参数当做元素的value。第三个参数可有可无,用于定义排序规则,仅由key决定,默认为less< Key>。

(1)map/multimap的构造函数

map<key,value> c;/* 定义一个空的map容器*/
map<key,value,greater< int>> c;/* 定义一个空的map容器,使用仿函数greater进行排序*/
map<key,value> c(first,last);/* 定义一个map容器并用first到last的元素去初始化*/

(2)容量函数

bool empty( )const;                            /* 判断map是否为空 */

size_type size( )const;                      /* 获取map的长度 */

size_type max_size( )const;             /* 获取map的最大长度 */

(3)迭代器函数

iterator begin();/* 返回map的首元素 */
const_iterator begin();/* 返回map的首元素 */

iterator end();/* 返回map的尾元素 */
const_iterator end();/* 返回map的尾元素 */

reverse_iterator rbegin();/* 返回map的尾元素 */
const_reverse_iterator rbegin();/* 返回map的尾元素 */

reverse_iterator rbegin();/* 返回map的尾元素 */
const_reverse_iterator rend();/* 返回map的首元素 */

(4)交换函数

void swap(set& str);/* 交换两map的元素 */

(5)插入和删除函数

pair<iterator,bool>insert(const value_type& x);/* 返回值为pair类型的迭代器指针first代表插入元素的位置,第二个为bool类型,表示插入是否成功 */

iterator insert(iterator it,const value_type& x);/* 在集合it位置插入元素x。自动排序,不起作用 */

void insert(const value_type& first,const value_type& last);/* 插入迭代器first到last之间的元素到集合中 */

iterator erase(iterator it);/* 清除元素it */
iterator erase(iterator first,iterator last);/* 清除迭代器first到last之间的元素 */
size_type erase(const key& key);/* 清除关键值为key的元素 */

void clear()const; /* 清空map元素,等同于erase(map::begin(),map::end()) */

map插入元素的四种方法:
方法一:例:
map<int, string> mp;
mp.insert(pair<int,string>(1,"aaaaa"));
 
方法二:例:
map<int, string> mp;
mp.insert(make_pair<int,string>(2,"bbbbb"));
 
方法三:例:
map<int, string> mp;
mp.insert(map<int, string>::value_type(3,"ccccc"));
 
方法四:例:
map<int, string> mp;
mp[4] = "ddddd";
 
四种方法异同:
前三种方法当出现重复键时,编译器会报错,而第四种方法,当键重复时,会覆盖掉之前的键值对。

(6)容量、搜寻、统计函数

size_type count( const Key& _Key )const;   /* 获取元素_Key的个数*/

iterator find(const Key& _Key)const;
const_iterator find(const Key& _Key)const;
/* 返回键值为_Key的元素的位置,类型为迭代器,未找到返回end() */

const iterator lower_bound(const Key& _Key)const;/* 返回键值大于_Key前面的那个元素或等于_Key的位置类型为迭代器 */

const iterator upper_bound(const Key& _Key)const;/* 返回键值大于_Key的元素的迭代器位置 */

pair< iterator,iterator>equal_range(const Key& _Key)const;/* 函数返回类型为迭代器对(pair),该迭代器对的两个迭代器分别指向集合中元素键值大于_Key前面的那个元素或等于_Key的位置(first)和集合中键值大于参数_Key的第一个元素(second) */

(7)元素比较函数

key_compare key_comp()const;           /* 键值比较函数 */
value_compare value_comp()const;    /* 实值比较函数 */

例如以下代码返回值为 1,即第一个元素键值小于第二个元素的键值:

#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <map>
int main()
{
    std::map<int,double> mymap;
    mymap.insert(std::pair<int,double>(1,1.1));
    mymap.insert(std::pair<int,double>(2,2.1));
    
    std::map<int,double>::key_compare kc = mymap.key_comp();
    std::cout<<std::endl;
    std::cout<<kc(1,2)<<std::endl;
    
    std::cin.get();
	return 0;
}

(8)获取内存分配器

Allocator get_allocator(void);/* 获取集合的内存配置器首地址 */

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值