您的位置:首页 > 编程语言 > C语言/C++

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

2013-01-22 13:04 423 查看
——关联容器(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类型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: