关联容器 - 1【C++ Primer 学习笔记 - 第十章】

关联容器的类型:
1、map    关联数组,元素通过键来存储和读取,以键值(key-value)对的形式组织
2、set      大小可变的集合,支持通过键实现的快速读取
3、multimap    支持同一个键多次出现的 map 类型
4、multiset     支持同一个键多次出现的 set 类型

set 和 map 类型的对象所包含的元素都具有不同的键不允许为同一个键添加第二个元素
如果一个键必须对应多个实例,则需要使用 multimap 或者 mulitset 类型


定义在 utilitiy 头文件中的 pair 类型

pair 类型提供的操作
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的类型
p1 < p2pair 对象之间的小于运算
p1.first < p2.first 或者 !(p2.first < p1.first) && p1.second<p2.second,则:true
p1 == p2p1、p2 的 first 和 second 成员依次相等,则 p1、p2 相等
p.first返回 p 中名为 first 的数据成员
p.second返回 p 中名为 second 的数据成员














pair 包含2个数据值。与容器一样,是一种模板类型。
pair 类的成员都是公有的,可以直接访问数据,分别命名为 first、 second

pair<string, vector<int> > word_count;
pair<string, string> author("James", "Joyce");
typedef pair<string, string> Author;
Author zhang("Zhang", "San");
Author li("Li", "Si");

if(zhang.first=="Zhang" && zhang.second=="San")
	cout << "Found Author ZhangSan" << endl;

string first = "Mo", second = "Yan";
Author mo = make_pair(first, second);


map 的构造函数
map<k, v> m;创建一个名为 m 的空 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>






键类型必须定义 < 操作符,而且是 严格弱排序的,即,键类型数据上的小于关系。


map 类定义的类型
map<K, V>::key_type在 map 容器中,用作索引的键的类型
map<K, V>::mapped_type在 map 容器中,键所关联的值的类型
map<K, V>::value_typepair 类型,
first 元素具有 const map<K,V>::key_type 类型
second 元素具有 map<K,V>::mapped_type 类型





value_type 是 pair 类型,值成员可以修改,键成员不能修改

map 类额外定义的类型别名,
map<string, int>::key_type 是 string 类型,
map<string, int>::value_type 是 int 类型


map<string, int> word_count;
word_count["Anna"] = 1;
// 上述代码,执行过程:
// 1、在word_count 查找 "Anna",未找到
// 2、插入新的键值对,键为"Anna",值初始化 0
// 3、读取新插入的键值对,然后赋值为1
// 用下标访问 map 的情况,不同于数组和vector,
// 下标访问 map 中不存在的元素,将导致在该 map 中增加一个响应元素

vector 的下标操作返回的类型,和 vector迭代器解引用 获得的类型相同。
但是,
map 的下标操作返回左值,是 mapped_type 类型,
而 map 迭代器返回 value_type 类型,
包含 const key_type 、  mapped_type 的 pair 对象


// 此例演示了 map 类型,特殊的下标行为在编程中的意义
map<string, int> word_count;
string word;
while(cin >> word)
	++word_count[word];



map 容器提供的 insert 操作
m.insert(e)e 是一个 m 上的 value_type 类型的值。
如果 e.first 不在 m 中,则,插入新元素,值为 e.second
如果 e.first 已存在,m 不变。
该函数返回一个pair 类型的对象,
包含,指向键为 e.first 的元素的 map 迭代器,
和 一个bool 类型的对象,表示是否成功插入元素
m.insert(beg, end)beg 和 end 是标记元素范围的迭代器,
其中元素必须为 m.value_type 类型的键值对。
对于该范围内的所有元素,如果它的键在 m 中不存在,
则插入该键值对。返回 void 类型
m.insert(iter, e)e 是一个 m 上的  value_type 类型的键值对。
如果 e.first 在 m 中不存在,则创建新元素,
并以迭代器 iter 为起点搜索新元素存储的位置。
返回一个迭代器,指向 m 中具有给定键的元素

















map<string, int> word_count;
word_count.insert(map<string, int>::value_type("Anna", 1));

// 此处 "Anna" 键,已经存在,不会作任何操作
word_count.insert(make_pair("Anna", 1));
typedef map<string, int>::value_type valueType;
word_count.insert(valueType("Zhang", 2));

string word;
while(cin >> word)
{
	pair<map<string, int>::iterator, bool> ret = word_count.insert(make_pair(word, 1));

	// 已存在,插入失败,ret.second 为 false
	if(!ret.second)
		++ret.first->second;
		// ret.first 类型为 map<string, int>::iterator
		// 该迭代器指向 map<string, int>::value_type		
}


map 中的查询操作

m.count(k)
返回 m 中 k 的出现次数,只能是0 或者 1

m.find(k)
如果 m 中存在按 k 索引的元素,则返回指向该元素的迭代器。否则,返回超出末端迭代器

map<string, int> word_count;
int occurs = 0;

// 此处实际上使用了2次查找
// 因为下标操作,总是会查找一次
if(word_count.count("fooBar"))
	occurs = word_count["fooBar"];

// 此处只查找了一次
map<string, int>::iterator iter = word_count.find("fooBar2");
if(iter != word_count.end())
	occurs = iter->second;


从 map 中删除元素
m.erase(k)
删除 m 中 键为 k 的元素。返回 size_type 类型,表示删除的个数。只能是0 或者 1

m.erase(p)
删除 m 中迭代器 p 所指向的元素。p 指向的元素必须存在,且不能是 m.end()。返回 void

m.erase(b, e)
删除由迭代器b 和 e 标记的范围。返回 void


map<string, int> word_count;
word_count.insert(make_pair("z", 1));
word_count.insert(make_pair("a", 2));
map<string, int>::iterator iter = word_count.begin();
while( iter!= word_count.end())
{
	cout << "Key: " << iter->first << ", ";
	cout << "Value: " << iter->second << endl;
	++iter;
}
// 结果是:
// Key: a, Value: 2
// Key: z, Value: 1
// 说明,使用迭代器遍历 map 容器时,迭代器指向的元素按照 键的升序排列


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值