C++:关联容器(pair、map、set)
2016-02-29 10:22
375 查看
关联容器和顺序容器的本质区别:
关联容器是通过键存取和读取元素、顺序容器通过元素在容器中的位置顺序存储和访问元素。
两个基本的关联容器类型是map和set。
map的元素以键-值对的形式组织:键用作元素在map的索引,而值则表示所存储和读取的数据。set仅包含一个键,并有效地支持关于某个键是否存在的查询。
set和map类型的对象不允许为同一个键添加第二个元素。如果一个键必须对应多个实例,则需使用multimap或mutiset类型,这两种类型允许多个元素拥有相同的键。
创建一个pair对象,两个元素的类型分别是T1,T2类型,采用初值进行初始化
创建一个pair对象,两个元素的类型分别是T1,T2类型,采用v1,v2分别进行初始化
以v1、v2的值创建一个pair对象,类型分别是v1、v2的类型
返回p中第一个公有数据成员
返回p中第二个公有数据成员
创建一个名为m1的空的map对象,其键和值的类型分别为k、v
创建m2的副本m,m与m2的类型必须有相同的键类型和值类型
创建map类型的对象m,存储迭代器b和e标记范围内所有元素的副本,元素的类型必须转换为pair
map迭代器进行解引用将产生pair类型的对象,first是键,second是值,:
因此,使用下标访问map与使用下标访问数组或vector的行为不同,用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值。这一特性可以使程序简练:
e是一个用在m上的value_type类型的值,如果e.first不在m中则插入一个值为.second的新元素,否则,即该键值在m中已经存在则保持不变,该函数返回一个pair新类型,包含一个指向键值为e.first的元素的map迭代器,以及一个bool类型的对象,表示是否插入该元素
插入beg、end标记范围内的元素,如果该元素的m.first已经存在则不插入,否则插入。返回void类型。
如果e.first不在m中,则创建新元素,并以迭代器iter为起点搜索新元素的存储位置,否则返回一个迭代器,指向m中具有给定键的元素。
返回k在m中出现的次数,在map中只是返回0、1(即存在或不存在)
如果k在m中的键值存在,则返回相应的迭代器,否则返回超出末端的迭代器
删除m中键为k的元素。返回值为被删除元素的个数,对于map容器而言,其值必然是0或1。
从m中删除迭代器p所指向的元素。返回值为void类型。
从m中删除一段由一对迭代器限定范围的元素。返回值为void类型。
list和set都是单列集合,他们有一个共同的父接口—collection。list是依次列出一个结合中的所有的元素,若集合中有重复的,同样列出,有序;set列出的集合中是不允许有重复的,也就是说里面有一个A对象和一个B对象,若是A.equals(B)==ture,那么用set方法列出的只会有一个,set集合默认是有序的,正向排序。一般遍历set里面的元素时使用iterator。
比如说:
你需要存某门课程全班同学的成绩,就需要用到map,因为每个人的键(姓名)不一样,值(成绩)也不一样。而如果你要统计这门课的作业提交情况,就可以用set,因为你只需要存储键(姓名),一个同学只有交了(true)和没交(false)两种情况。
关联容器是通过键存取和读取元素、顺序容器通过元素在容器中的位置顺序存储和访问元素。
两个基本的关联容器类型是map和set。
map的元素以键-值对的形式组织:键用作元素在map的索引,而值则表示所存储和读取的数据。set仅包含一个键,并有效地支持关于某个键是否存在的查询。
set和map类型的对象不允许为同一个键添加第二个元素。如果一个键必须对应多个实例,则需使用multimap或mutiset类型,这两种类型允许多个元素拥有相同的键。
1. pair类型
pair类型的初始化
在头文件utility中:
pair<T1,T2> p1;
创建一个pair对象,两个元素的类型分别是T1,T2类型,采用初值进行初始化
pair<T1,T2> p1(v1,v2);
创建一个pair对象,两个元素的类型分别是T1,T2类型,采用v1,v2分别进行初始化
make_pair(v1,v2);
以v1、v2的值创建一个pair对象,类型分别是v1、v2的类型
p.first
返回p中第一个公有数据成员
p.second
返回p中第二个公有数据成员
2. map关联数组
2.1 map初始化
map<k,v> m1
创建一个名为m1的空的map对象,其键和值的类型分别为k、v
map<k, v> m(m2)
创建m2的副本m,m与m2的类型必须有相同的键类型和值类型
map<k,v> m(b,e)
创建map类型的对象m,存储迭代器b和e标记范围内所有元素的副本,元素的类型必须转换为pair
2.2 map定义的类型
map<K,V>::key_type:在map中键的类型
map<K,V>::mapped_type:在map中键所关联的值的类型
map<K,V>::value_type:一个pair类型,它的first元素具有
const map<K,V>::key::type类型,而second元素则为
map<K,V>::mapped_type类型
map迭代器进行解引用将产生pair类型的对象,first是键,second是值,:
map<string,int>::iterator map_it = ord_count.begin(); cout<<map_it->first<<""<<map_it->second<<endl;
2.3 给map添加成员
使用下标访问map对象:在map中查找键值为x的元素。如果找到则返回它的值(类型是map<k,v>::mapped_type),否则插入一个新的对象,键值为x,值为
map<k,v>中v的默认初值。
因此,使用下标访问map与使用下标访问数组或vector的行为不同,用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值。这一特性可以使程序简练:
int main() { string str; map<string,int> wordCount; while(cin>>str) { ++wordCount[str]; } map<string,int>::iterator it_map = wordCount.begin(); cout<<"word"<<"\t\t"<<"count"<<endl; for(;it_map != wordCount.end();++it_map) cout<<it_map->first<<"\t\t"<<it_map->second<<endl; return 0; }
2.4 使用insert对map进行插入
m .insert(e)
e是一个用在m上的value_type类型的值,如果e.first不在m中则插入一个值为.second的新元素,否则,即该键值在m中已经存在则保持不变,该函数返回一个pair新类型,包含一个指向键值为e.first的元素的map迭代器,以及一个bool类型的对象,表示是否插入该元素
m.insert(beg,end)
插入beg、end标记范围内的元素,如果该元素的m.first已经存在则不插入,否则插入。返回void类型。
m.insert(iter,e)
如果e.first不在m中,则创建新元素,并以迭代器iter为起点搜索新元素的存储位置,否则返回一个迭代器,指向m中具有给定键的元素。
//用insert方法重写单词统计程序 map<string,int> word_count; word_count.insert(map<string,int>::value_type("aaa",1)); map<string,int> word_count; string word; while(cin>>word) { pair<map<string,int>::iterator,bool> ret=word_count.insert(make_pair<string,int>(word,1)); if(!ret.second)//如果没插入成功,证明原来已经存在键值,将统计值+1 { ++ret.first->second;// first是一个迭代器,指向插入的键 } }
2.5 查找和读取map中的元素:
m.count(k)
返回k在m中出现的次数,在map中只是返回0、1(即存在或不存在)
m.find(k)
如果k在m中的键值存在,则返回相应的迭代器,否则返回超出末端的迭代器
//读取元素而又不插入新元素 int occurs; map<string,int>::iterator it= word_count.find("foobar");//不存在,则返回end迭代器 if(it!=word_count.end())//可能找不到 { occurs=it.second; }
2.6 从map中删除元素
使用erase,与顺序容器功能一样:m.erase(k)
删除m中键为k的元素。返回值为被删除元素的个数,对于map容器而言,其值必然是0或1。
m.erase(p)
从m中删除迭代器p所指向的元素。返回值为void类型。
m.erase(b,e)
从m中删除一段由一对迭代器限定范围的元素。返回值为void类型。
//map对象的迭代遍历: map<string,int> word_count; map<string,int>::const_iterator iter = word_count.begin(); while(iter!=word_count.end()) { cout<<iter->second<<endl; iter++; }
2.7 map操作函数总结
//初始化 map<k,v> m1;//创建一个名为m1的空的map对象,其键和值的类型分别为k、v map<k, v> m(m2);//创建m2的副本m,m与m2的类型必须有相同的键类型和值类型 map<k,v> m(b,e);//创建map类型的对象m,存储迭代器b和e标记范围内所有元素的副本,元素的类型必须转换为pair<const k, v> //添加元素 m .insert(make_pair(a,b));//如果a不在m中则插入一个值为b的新元素,否则保持不变。 m[a]=b;//该方式下,如果a键不存在,则创建一个<a,b>,否则用b覆盖a键的值 //count或find查找元素 m.count(k);//返回k在m中出现的次数,在map中只是返回0、1(即存在或不存在) m.find(k);//如果k在m中的键值存在,则返回相应的迭代器,否则返回m.end() //erase删除元素 m.erase(k);//删除m中键为k的元素。返回值为被删除元素的个数,对于map容器而言,其值必然是0或1。 m.erase(iter);//删除m中迭代器iter指向的元素 //清空map m.clear(); //map的大小 int mSize=m.size(); //map的遍历 //正向迭代器方式 map<int, string>::iterator iter; for(iter = m.begin(); iter != m.end(); iter++) { cout<<iter->first<<' '<<iter->second<<end; } //反向迭代器方式 map<int, string>::reverse_iterator iter; for(iter = m.rbegin(); iter != m.rend(); iter++) { cout<<iter->first<<' '<<iter->second<<end; }
3. set类型
set只有键,没有值,所以它的vaule_type不是pair类型,而是
key_type类型。set也支持以上map的一系列操作,如
insert、find、count、erase等。
//初始化 set<int> s0 ;//创建一个名为s0的空的set对象 set<int, greater<int>> s1 ;//创建一个带大于比较器的set, 默认是小于比较器less<int> int a[3] = {1, 2, 3} ; set<int> s2(a, a + 3) ;//用数组初始化一个set set<int> s2(s1) ;//用拷贝构造函数初始化set,s2是s1的副本 set<int> s2(s1.begin(), s1.end()) ;//创建set类型的对象s2,并用两个迭代器所决定区间内的元素初始化 //添加元素 s.insert(a) ;//如果a不在s中则添加a,否则保持不变。 s.insert(s1.begin(), s1.end()) ;//使用迭代器,批量添加元素 //count或find查找元素 s.count(k);//如果s中存在k,则返回1,否则返回0 s.find(k);//如果k在s中存在,则返回相应的迭代器,否则返回s.end() //erase删除元素 s.erase(2);//删除键为2的元素 s.erase(iter);//删除迭代器iter指定的元素 s.erase(s.begin(), s.end()) ;//删除s内的所有元素 //清空set s.clear(); //set的大小 int sSize=s.size(); //遍历 //正向迭代器方式 set<int>::iterator iter; for(iter = s.begin(); iter != s.end(); iter++) { cout<<*iter<<end; } //反向迭代器方式 set<int>::reverse_iterator riter; for(riter = s.rbegin(); riter != s.rend(); riter++) { cout<<*riter<<end; }
4. list、set和map的区别和联系
三者都是有序的。list和set都是单列集合,他们有一个共同的父接口—collection。list是依次列出一个结合中的所有的元素,若集合中有重复的,同样列出,有序;set列出的集合中是不允许有重复的,也就是说里面有一个A对象和一个B对象,若是A.equals(B)==ture,那么用set方法列出的只会有一个,set集合默认是有序的,正向排序。一般遍历set里面的元素时使用iterator。
map <key,value>是一个双列的集合,里面有一个key,和一个value,其中value是真正存储值的变量。map存储的数据也是有序的,根据键(key)排序。其键(key)不能重复,但是其值(value)是可以重复的。
比如说:
你需要存某门课程全班同学的成绩,就需要用到map,因为每个人的键(姓名)不一样,值(成绩)也不一样。而如果你要统计这门课的作业提交情况,就可以用set,因为你只需要存储键(姓名),一个同学只有交了(true)和没交(false)两种情况。
相关文章推荐
- wav文件格式分析(代码 C++ )
- C语言中fflush函数的使用方法
- 《C++ Primer》之重载操作符与转换(中)
- 单链表的逆置-C++实现
- 算法代码实现之Union-Find,C++实现,quick-find、quick-union、加权quick-union(附带路径压缩优化)
- vs2010 C++创建和使用动态链接库(dll)
- C++语言-05-三大特性
- C语言_数组与排序
- C语言_循环语句
- C++ Super-FAQ 『Deconstructor』
- C语言_运算符的优先级
- [c++]win下utf8源文件编译运行后乱码,codeblocks编辑器
- C++编写安全OCX,IE不弹出安全提示
- c++在VS2010编译的程序在XP系统托盘气泡提示不成功解决办法
- C/C++: short , int , long , long long数据类型选用
- C++多态性理解
- C++多线程操作(火车售票系统线程同步)
- c++中信息隐藏的实现
- c/c++ (void) var语句的作用与ignore_unused的对比
- c++面试笔试集锦