C++关联容器
来源:互联网 发布:淘宝网购支付宝限额 编辑:程序博客网 时间:2024/06/06 00:30
1.关联容器是通过关键字来保存和访问数据的。关联容器分为两大类:map和set。其中,map是通过键值对来操作的,这里的键就是关键字,值就是对应的数据。
例如:
map<int ,int> m;定义了一个空的map变量m,它的关键字类型是int,关键字对应的值的类型是int。可以将map理解成为函数,关键字是自变量,关键字对应的值是因变量。
set,这是一个集合类。它的关键字和值是相同的。也就是说定义了一个set,它的关键字和值是同一个值。例如:
set<int> s;定义了一个空的set类型的变量s,它里面可以存储int类型的数据,它的关键字和值都是同一个,类型都是int。set和数学上的集合是一样的,都有一个特点,唯一性。也就是说,set中的元素,一般不能重复出现。因此,我们有时候使用set,来判断一个关键字是否在一个某一个集合中。
2.map和set有很多种类:它们通过前面的修饰词来加以区分。修饰词主要有:unordered,multi,一个表示无序,另外一个表示关键字可以重复。例如:unordered_multiset表示,一个无序的,关键字可以重复的set。这里的无序的实现数据结构是哈希函数。
map和set都是模板。
3.关于定义关联容器,可能当你去读C++ primer这本书时,会发现,在定义关联容器时有好多方法。其实,通过我的时间发现,这和你的编译环境,编译器是有很大的联系的,又看看,你的编译器对C++11支持多少。
例如:
定义:map<string,string> word={ {"A","a"},{"B","b"}};//对于这样的定义,不同的编译器,编译之后的结果也是不一样的。想VS2012好像就不能支持。
4.因为,关联容器的关键字和对应值的类型,没有强制的限制,也就是说,自己定义的类也可以当做关键词或者对应的值的类型来使用,但是,我们要注意,无论哪一种类型,要支持比较运算符<,或者要支持比较方法。如果不支持,麻烦自定义。
5.pair类型:
在之前我们说cocos2dx中读取excle文件时,最后提到了pair类型,这里我们对其进行更加详细的说明。
pair类型,这是一个标准库类型。pair类型,保存两个数据,在初始化的时候,需要传递两个类型。pair的两个数据成员是公共的。
6.关联容器的操作:
6.1额外的类型别名:
value_type:对于set来说,这个和关键字的类型是一样的。对于map来说,这个的类型是:pair<const key_type,mapped_type>
例如:
map<int ,int >::value_type var;//var的类型就是pair<const int,int>。
mapped_type:每个关键词关联的类型。这个只使用与map,说白了,就是值的类型
例如:map<int ,int >::mapped_type var;//var的类型就是int
key_type:就是关键字的类型
6.2关于map的操作.
6.2.1要向map中添加元素,这个元素的类型,必须是pair类型。正如上面所说的,map中value_type是pair类型。因此,就像之前讲过的,要构造一个pair类型的数据,例如:make_pair<i,j>这就是构造一个pair类型的数据。
例如:
map<int,int> m1;//不能重复关键字auto it=m1.begin();map<int ,int>::key_type i;int j=10;for(int i=0;i<10;i++){auto p=m1.insert(make_pair(i,j));j++;}添加元素,使用函数insert()。
但是,要特别注意:insert的返回值问题。
template<class _Valty>typename enable_if<is_convertible<_Valty, value_type>::value,_Pairib>::typeinsert(_Valty&& _Val){// try to insert node with value _Val, favoring right side_Nodeptr _Newnode = this->_Buynode(_STD forward<_Valty>(_Val));return (_Insert_nohint(false,this->_Myval(_Newnode), _Newnode));}上面是insert的源码。编译环境VS2012
insert返回的值依赖于容器类型和参数。
如果是关键字不能重复的,insert返回一个pair类型值。这个值的first数据成员保存的是一个指向要插入元素的迭代器,second数据成员,是一个bool值,用来表示要插入的值,是否插入成功。
例如:
map<int,int> m1;//不能重复关键字auto it=m1.begin();map<int ,int>::key_type i;int j=10;for(int i=0;i<10;i++){auto p=m1.insert(make_pair(i,j));if(p.second)cout<<"插入的值:"<<p.first->second<<endl;j++;}在这段代码中,我们将i,j插入到map中。在这里,p的类型就是一个pair类型.first数据成员,是一个迭代器,指向插入元素的一个迭代器。这个迭代器中,存放的就是要插入的这两个数i和j的值。p的second元素是一个bool类型的数据,表示是否插入成功。
这段代码,单步调试的结果:
最后的结果值:
6.2.2其次,就是迭代器的问题。
当解引用一个关联容器的迭代器是,我们将得到一个值的value_type的一个引用。
在map中,value_type是一个pair。而且,first还是const类型的,所以,不能修改first指向的数据。
在set中,set和map差不多,也是只能读取,不能修改。
例如:
for(auto it=m1.begin();it!=m1.end();it++){cout<<"first:"<<it->first<<"second:"<<it->second<<endl;要注意,当使用迭代器遍历map和set时,迭代器是按照关键字的升序顺序来遍历的。
6.2.3 删除元素。
删除元素,使用ereas函数,传入的参数可以是关键字,迭代器,迭代器的范围。也就是说,通过这个函数,可以删除一个范围的元素。
例如:
m1.erase(1);//删除对应关键词的元素
这一步操作之后,会将关键字为1,这个键值对删除。
6.2.4下标运算符和访问元素
map是可以支持下标运算符的。set是不支持下标运算符的。
例如,之前定义的m1这个变量,如果,我们这样操作:m1[11]。显然,我们没有11这个关键字,但是如果使用下标运算符之后,他会将11这个关键字添加到m1这个map中,而且,还会初始化。
因此,我们要知道,一个关键字,是否在一个map中,最好使用find和cout函数。
这两个函数的源码:
// 返回关键字的个数//size_type count(const key_type& _Keyval) const//{// count all elements that match _Keyval//_Paircc _Ans = equal_range(_Keyval);//size_type _Num = 0;//_Distance(_Ans.first, _Ans.second, _Num);//return (_Num);//}p.count(1);count这个函数,是判断这个关键字在map中,是否存在,而且,存在几个。
//这个函数适合检查该元素是否在关联容器中,传递的参数是关键词的类型//源码//iterator find(const key_type& _Keyval)//{// find an element in mutable sequence that matches _Keyval//iterator _Where = lower_bound(_Keyval);//return (_Where == end()//|| _DEBUG_LT_PRED(this->_Getcomp(),//_Keyval, this->_Key(_Where._Mynode()))//? end() : _Where);//}auto temp= p.find(1);
find函数,只关心关键字是否存在在map中。
这就是今天我们要和大家分享的关于C++关联容器的知识,欢迎大家指正!
- C++primer 关联容器
- 《C++primer》关联容器
- C++MAP关联容器
- C++map关联容器
- 数据结构-关联容器(C++)
- C++----关联容器
- 关联容器(Java/C++)
- 【C/C++】关联容器pair map set
- C++-关联容器类型map
- c++Primer笔记(十 关联容器)
- C ++ primer 中说的关联容器
- C++primer U10 读书笔记 关联容器
- 【足迹C++primer】36、使用关联容器
- 【足迹C++primer】37、关联容器概述
- C++STL之关联容器【map】【set】
- 学习C++——关联容器
- c++primer(十)关联容器
- C++primer学习:关联容器(1)
- 保存文件
- start.S解析8
- bzoj 1597: [Usaco2008 Mar]土地购买(斜率优化dp 例题)
- N的阶乘
- uva536-Tree Recovery-二叉树遍历
- C++关联容器
- 【MySQL】存储过程、游标、循环简单实例
- Shell中read的选项及用法
- 玩转AndroidStudioIDE
- android 简单拨号器 代码
- handler和looper在子线程的调用
- CentOS从php5.3升级到php5.5
- ZOJ 1831 Substitution Cypher
- Bestcoder Pro.ID 2013 蟠桃记