《C++ Primer》学习笔记——关联容器

一,      pair类型

pair<T1, T2> p1;

创建一个空pair指针,两个元素分别是T1,T2类型,采用值初始化

pair<T1, T2> p1(v1, v2);

first成员初始化为v1second成员为v2

make_pair(v1, v2)

创建新的pair对象

p1 < p2

 

p1 == p2

 

p.first

返回first成员

p.second

返回second

可以再定义时初始化;

pair类型的使用相当繁琐,因此用typedef来简化其声明和使用;

两个成员都是公有的;

pair<string, string> next_auth;

string first, last;

while(cin >> first >> last){

       nest_auth = make_pair(fist, last);

}

二,      关联容器

1,如果希望有效地存储不同值的集合,使用setmap更适用于需要存储和修改每个键所关联的值的情况。

 

三,      map类型

1,本质在于元素的值与某个特定的键相关联,而非通过所在位置来获取,每个键只出现一次。

2,必须包含map头文件。

3,map的声明和初始化

map<k, v> m;

创建一个空map对象

map<k, v> m(m2);

必须具有相同的键类型和值类型

map<k, v> m(b, e);

存储be之间的所有副本。元素的类型必须能转换为pair<const k, v>

 

4,map定义的类型

map<K, V>::key_type

键类型,键为const

map<K, V>::mepped_type

值类型

map<K, V>::value_type

pair类型,first为键类型,second为值类型

map迭代器进行解引用将产生pair类型的对象;

 

5,键类型的约束:

键不但有一个类型,而且还有一个相关的比较函数,即 < 操作符:满足与自身比较导致false,传递性,不能互相小于,互相不存在“小于”即为相等。

 

6,用下标访问map

如果不存在,则添加一个键为下标值的新元素;

下表操作符返回左值;

 

7,map::insert的使用

m.insert(e)

evalue_type类型;

如果e.first不存在,则插入;若存在,则保持不变;

返回一个pair类型对象,包含指向键为e.first的元素的迭代器,和一个bool类型的对象,表示是否插入,即pair<map<string, int>::iterator, bool>类型。

m.insert(beg, end)

begend中间的元素为m.value_type类型;

对所有的元素,只要该键不存在,则插入;

返回void

m.insert(iter, e)

em.value_type;

不存在,则创建,以iter为起点搜索新元素存储的位置;

返回迭代器指向有给定键的元素;

传递给insert的实参太繁琐,两种方法改进:一是用make_pair(k, v),二是用typedef

 

8,查找并读取map中的元素

如果只想查找或者读取元素而不想新建元素怎么办?

m.count(k)

返回mk的出现次数

m.find(k)

存在k索引的元素,返回指向该元素的迭代器;

不存在,则返回超出末端迭代器end

if (m.count(“key”))

        value = m[“key”]; 

以上实现了读取但不插入,但实际上做了两次查找。

map<string, int>::iterator it = m.find(“key”);

if (it != m.end())

        value = it->second;

以上只进行了一次查找。

 

9,map对象中删除元素

m.erase(k)

返回size_type类型,表示删除的元素个数

m.erase(p)

删除迭代器p指向的元素;

p必须指向存在的元素,不能为end

返回void

m.erase(b, e)

be必须标记m中一段有效返回:e可以指向end

be可以相等(删除范围为空),否则b要在e之前;

返回void

 

10,            map对象的迭代遍历

map<string, int>::const_iterator map_it = word_count.begin();

while (map_it != word_count.end()) {

        … …

        ++map_it;

}

 

四,      set类型

1,set是单纯键的集合,每个键只出现一次,即对同一键多次插入实际只插入一次。

2,必须包含set头文件。

3,set的操作和map几乎相同,两个例外:没有下表操作符;没有mapped_value类型。

4,set添加元素

s.insert(k)

如果e.first不存在,则插入;若存在,则保持不变;

返回一个pair类型对象,包含指向键为k的元素的迭代器,和一个bool类型的对象,表示是否插入

s.insert(beg, end)

begend中间的元素为s.value_type类型;

对所有的元素,只要该键不存在,则插入;

返回void

 

5,获取set元素

因为没有下表操作,所以获取元素只能用find运算;如果只需判断是否存在,则用count运算。

set的键也为const,所以只能做读操作,不能做写操作。

 

五,      multimapmultiset类型

1,允许一个键对应多个值,因此与mapset的操作有所不同。

2,multimapmultiset的操作分别与mapset的操作相同,只有一个例外:multimap不支持下标运算,因为一个键可能对应多个值。

但由于一个键可以对应多个值,因此各个操作都以不同的方式做出了修改,可以处理多个值。

3,元素的添加和删除

每次调用insert都会添加一个元素,无论该键是否存在;

带有一个键参数的erase将删除所有元素,并返回元素个数;

带有一个或一对迭代器参数的版本只删除指定的元素,并返回void类型;

4,查找元素

a,mapset中的元素是按顺序存储的;multimapmultiset中对应同一个键的元素将相邻存放。

b,使用findcount操作

typedef multimap<K, V>::size_type sz_type;

sz_type entries = multimap.count(k);

multimap<K, V>::iterator iter = multimap.find(k);

for (sz_type cnt = 0; cnt != endl; ++cnt, ++iter){… …}

 

c, 面向迭代器的解决方案

m.lower_bound(k)

返回迭代器,指向键不小于k的第一个元素

m.upper_bound(k)

返回迭代器,指向键大于k的第一个元素

适用于mapset但更常用于multimapmultiset

调用这两个函数将产生一个迭代器范围,指示出所关联的所有元素;

如果该键不存在,则返回指向该键应该插入的位置的迭代器;

返回值有可能是超出末端迭代器;

typedef multimap<K, V>::iterator iter;

iter beg = m.lower_bound(k),

    end = m.upper_bound(k);

while (beg != end){

         … …

         ++beg;

}

 

d,equal_range函数

m.equal_range(k)

返回一个迭代器的pair对象:

first成员等价于m.lower_bound(k)

second对象等价于m.upper_bound(k)

pair<iter, iter> pos = m.equal_range(k);

while(pos.first != pos.second){

         cout << pos.first->second << endl;

         ++pos.first;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值