《C++ Primer》 第10章 关联容器

来源:互联网 发布:java应用服务器有哪些 编辑:程序博客网 时间:2024/06/06 05:30
——关联容器(associative container)支持通过键来高效地查找和读取元素。
@学习摘录093:关联容器和顺序容器的本质差别
——关联容器通过键(key)存储和读取元素;
——顺序容器则通过元素在容器中的位置顺序存储和访问元素。
@学习摘录094:关联容器的主要特点
——关联容器的独特之处在于支持键的使用。
——关联容器根据键的次序排
——在迭代遍历关联容器时,我们可以确保按键的顺序访问元素,而与元素在容器中的存放位置完全无关。(与插入顺序也无关)
@学习摘录095:关联容器的类型
——1.  map     关联数组;元素通过键来存储和读取
——2.  set           大小可变的集合,支持通过键实现的快速读取
——3.  multimap      支持同一个键多次出现的map类型
——4.  multiset       支持同一个键多次出现的set类型

@学习摘录096:两种基本关联容器的基本特点
——1. map的元素以键-值(key-value)对的形式组织。
—— 附:键,用作元素在map的索引。
——2. set仅包含一个键,能有效地支持关于某个键是否存在的查询。
@学习摘录097:四种关联容器需要注意的地方
——1. set 和 map类型的对象所包含的元素都具有不同的键,不允许为同一个键添加第二个元素。
——2. multimap和multiset 类型允许多个元素拥有相同的键,即用于一个键必须对应多个实例的情况下。(这两种类型不支持下标运算)
第一节:pair类型——#include <utility>
@学习摘录098:pair的创建与初始化
——pair<string, int> elem(“OK”, 110);  // holds a string and an int
——pair<string, vector<int> > line;    // holds string and vector<int>
@学习摘录099:pair对象的操作
——pair类,可直接访问其数据成员:成员都是公有的,分别命名为first和second
——pair< string, int> elem;
——elem.first = “OK”;
——elem.second = 3;
——cout << elem.first << elem.second; // 就这样,就给它们赋值了。

@学习摘录100:生成新的pair对象(make_pair)
——pair<string, string> next_auth;
——string first, last;
——while(cin >> first >> last)
——{
——// generate a pair from first and last
——next_auth = make_pair(first, last); 
——// process next_auth..
——}

第三节:map类型——#include <map>
——map类型通常可理解为“关联数组”——通过键获取值,键-值相关联。
@学习摘录101:键类型的约束
——默认情况下标准库使用键类型定义 < 操作符来实现键的比较。
——所用的比较函数必须在键类型上定义严格弱排序(strict weak ordering)
摘录有想101:
——这也就是说,map<first, second> 中的first类型必须支持 < (小于)操作符。
@学习摘录102:map类定义的类型
——map<K, V>::key_type      在map容器中,用作索引的键的类型
——map<K, V>::mapped_type  在map容器中,键所关联的值的类型
——map<K, V>::value_type     一个pair类型,它的first元素具有key_type类型,second元素具有mapped_type类型
@学习摘录103:map类定义类型的访问方法及需要注意的地方
——当使用了map<K, V>::value_type时,该类型中的key_type类型是const性质,不可修改。
——当使用了map<K, V>::iterator时,该类型中的key_type类型是const性质,不可修改。
摘录有想103:
——即 map<string, int> ok; map<string, int>::value_type vt; map<string, int>::iterator = ok.begin();
——vt -> first; 只能读取,不能赋值。 iterator -> first也是只能读取不能赋值。
@学习摘录104:下标在map中的行为
——假如定义了一个名为ok的map<string, int>对象
——用下标操作ok[“in”] = 12 会有以下结果:
——当in存在,赋ok -> second值为12;
——当 in 不存在,新建(即插入) ”in” 元素并赋值为12.

摘录有想104
——与顺序容器不同的一点是,用下标访问有可能会使map容器添加一个新的元素。 Good !
@学习摘录105:map中常用的insert操作
——m.insert(make_pair(“ok”, 12);
——m.insert(map<string, int>::value_type(“ok”, 1);
——m.inert(map<string, int>:: iterator a = m.begin(), map<string, int>::iterator b=++a );
——这三种操作,返回的都是void类型。
@学习摘录106:查找map中的元素
——m.find(k); 返回迭代器,存在,返回符合位置的迭代器,不存在,返回超出末端迭代器。
——m.count(k); 返回m中k的出现次数。
摘录有想106:
——count 操作根据map的性质,只能回返回0或1.
@学习摘录107:从map中删除元素
——// erase of a key returns number of element removed
—— if(word_count.erase(removal_word) )
——      cout << “ok: “ << removal_word << “ removed\n”;
—— else cout << “oops: “ << removal_word << “ not found! \n”;
——m.erase(k) 删除m中键为k的元素。返回size_type类型的值,表示删除的元素个数。
第五节:multimap和multiset类型
@学习摘录108:multimap和multiset类型元素的添加
——由于键不要求是唯一的,因此每次调用insert总会添加一个元素。
——multimap<string, string> authors;
——// adds first elemt with key a
—— authors.insert(make_pair( string(“a”), string(“b”) );
——ok: adds second element with key a
——authors.insert(make_pair(string(“a”), string(“c”) );
@学习摘录109:multimap和multiset类型元素的删除
——带有一个键参数的erase版本将删除拥有该键的“所有”元素,并返回删除元素的个数。
——multimap<string, string> ::size_type cnt = authors.erase( “a”);
@学习摘录110:multimap和multiset类型元素的查找――第一种方法
——直接见实例,当使用iter与find结合时,iter能保存所有find找到的键的结果。
// author we’ll look for
string search_item(“A”);
typedef multimap<string, string>::size_type sz_type;
sz_type entries = authors.count(search_item);
// get iterator to the first entry for this author
multimap<string, string>:: iterator iter = authors.find(search_item);
// loop through the number of entries there are for this author 
for(sz_type cnt = 0; cnt != entries; ++cnt, ++iter)
   cout << iter -> second << end;  // print each title
——上例中,count函数求出某键出现次数,而find则返回一个迭代器,指向第一个正在查找的实例。
@学习摘录110:multimap和multiset类型元素的查找――第二种方法  Good !
——m.lower_bound(k)  返回一个迭代器,指向键不小于k的第一个元素
——m.upper_bound(k)  返回一个迭代器,指向键大于k的第一个元素
// definitions of authors and search_item as above
// beg and end denote range of elements for this author
typedef multimap<string, string>::iterator authors_it;
authors.it beg = authors.lower_bound(search_item);
authors.it end = authors.upper_bound(search_item);
// loop through the number of entries there are for this author
while( beg != end)
{
  cout << beg -> second << endl;   // print each title
  ++beg;
}
摘录有想110:
——这里利用了迭代器取得元素在multimap中的区间,能这样操作是因为,在multimap中,它的元素是以“键”的 < (小于)的顺序排序的.   Good !

@学习摘录111:multimap和multiset类型元素的查找――第三种方法
——m.equal_range(k)  返回一个迭代器的pair对象,它的first成员等价于m.lower_bound(k),它的second成员等价于m.upper_bound(k);
——直接见实例:
typedef multimap<string, string>::iterator authors_it;
// definitions of authors and search_item as above
// pos holds iterators that denote range of elements for this key
pair<authors_it, authors_it> pos = authors.equal_range(search_item);
// loop through the number of entries there are for this author
while(pos.first != pos.second)
{
  cout << pos.first -> second << endl;  // print each title
  ++pos.first;
}
摘录有想111:
——这种使用方法,相当于第二种方法的简化,只是引用了一种pair类型。
@学习摘录112:*operator(解引用操作符在map、set、multimap、multiseet)
——在这些应用的时候,解引用操作符将生成一个value_type类型的值。
——对于map和multimap容器,value_type是pair类型。