关联容器和顺序容器的差别:
关联容器的存储和访问是按照键值的,map的键值有很多个,set的键值有一个,顺序容器的存储和访问是按照位置的。就是一个与键值有关,另一个与位置有关,与位置有关的,随机性比较好。
如果要多个元素拥有相同的键值的话,那么multimap和multiset是比较好的选择。
关于utility标准库中pair的定义:
pair<T1,T2> p | 创建一个空的pair对象,类型分别是T1和T2,采用值初始化 |
pair<T1,T2> p(v1,v2); | 创建一个pair对象p,用值初始化,first成员为v1,second成员为v2 |
make_pair(v1,v2); | 以 v1 和 v2 值创建一个新 pair 对象,其元素类型分别是 v1 和 v2 的类型 |
p1<p2 | 遵循字典排序的比较,如果 p1.first < p2.first 或者 !(p2.first < p1.first) && p1.second < p2.second,则返回 true |
p1 == p2 | p1.first==p2.first&&p1.second==p2.second |
p.first | 返回 p 中名为 first 的(公有)数据成员 |
p.second | 返回 p 中名为 second的(公有)数据成员 |
pair 包含两个数据值。与容器一样,pair 也是一种模板类型。但又与之前介绍的容器不同,在创建 pair 对象时,必须提供两个类型名:pair 对象所包含的两个数据成员各自对应的类型名字,这两个类型不一定相同。这对于理解map有很大的帮助,map的键和值的类型不一定一样。
pair<string, string> anon; // holds two strings
pair<string, int> word_count; // holds a string and an int
pair<string, vector<int> > line; // holds string and vector<int>
10.1编写程序读入一系列 string 和 int 型数据,将每一组存储在一个 pair 对象中,然后将这些 pair 对象存储在 vector 容器里:
#include<iostream> #include<string> #include<utility> #include<vector> using namespace std; int main() { vector< pair<string,int> > vp; string key; int val; while(cin>>key>>val){ vp.push_back(pair<string,int>(key,val)); if(0==val) break; } cin.clear(); for(vector< pair<string,int> >::iterator iter = vp.begin();iter!=vp.end();iter++){ cout<< iter->first << iter->second <<endl; } return 0; }10.2pair对象的创建有三种办法:
pair<t1,t2> p; pair<t1,t2> p(v1,v2); make_pair(v1,v2);
关联容器不提供 front、 push_front、 pop_front、back、push_back 以及 pop_back 操作。关联容器不能通过容器大小来定义。
10.3描述关联容器和顺序容器的差别:关联容器通过键 key 存储和读取元素, 而顺序容器则通过元素在容器中的位置顺序存储和访问元素。
10.4 list、vector、deque、map 以及 set 类型分别适用的情况:
list类型适用于需要在容器的中间位置插入和删除元素的情况,如以无序的方式读入一系列学生的数据;
vector类型适用于需要随机访问元素的情况。如:在学号为1…n的学生中,访问第 x 学号的学生的信息。
deque类型适用于在容器的尾部或首部有插入和删除元素情况。如:对服务窗口先来先服务的情况。
map适用于需要 key – value 对的集合的情况。如:字典电和话簿的建立和使用。
set类型适用于使用键集合的情况。例如,黑名单的建立和使用。
map 对象的定义: map<string , int> mymap; //空的map,名为mymap
map的构造函数:
map<k , v> m; 创建一个名为m的空map对象,键值类型分别为:k、v
map<k , v> m(m2); 创建一个名为m的map对象,键值类型分别为:k、v,然后用m是m2的副本
map<k , v> m(b , e); 创建一个名为m的map对象,键值类型分别为:k、v,存储迭代器 b 和 e 标记的范围内所有元素的副本。
10.5 定义一个 map 对象,将单词与一个 list 对象关联起来,该 list 对象存储对应的单词可能的行号。
map< string , list<int> > mp;
10.6 可否定义一个 map 对象以 vector<int>::iterator 为键关联 int 型对象?如果以 list<int>::iterator 关联 int?对于每种情况,如果不允许,请解释其原因。
可以定义一个map对象以vector<int>::iterator 和 pair< int, string > 为键关联int 型对象。
不能定义list<int>::iterator 关联 int?,因为键类型必须支持 < 操作,而list容器的迭代器类型不支持<操作。 pair<int, string>关联int可以。
map 类定义的类型:
map<k,v>::key_type 键类型
map<k ,v>::mapped_type 关联的值的类型
map<k,v>::value_type 一个 pair 类型,它的 first 元素具有 const map<K, V>::key_type 类型,而 second 元素则为 map<K, V>::mapped_type 类型
value_type 是 pair 类型,它的值成员可以修改,但键成员不能修改。
map 迭代器进行解引用将产生 pair 类型的对象。
10.7 对于以 int 型对象为索引关联 vector<int> 型对象的 map 容器,它的 mapped_type、key_type 和 value_type 分别是什么?
vector<int > 、 int 、 pair<const int, vector< int> >
10.8 编写一个表达式,使用map的迭代器给其元素赋值。
map< string, int > m;
map< string, int >::iterator map_it = m.begin();
map_it->second = val; // 只能对map的值成员元素赋值。不能对键进行赋值。