关联容器(map和set,支持高效的关键字查找和访问。key-value相对应,key起到索引的作用,value是和key相关联的数据)

在这里插入图片描述


使用关联容器

  • map的使用
  • map的意义在于快速找到与key对应的数据,并进行相应的操作
map<string, size_t> word_count; //string 到size_t的空map
string word;
while(cin>> word)
		++word_count[word]; //此时的就是value的值进行了加操作
for(const auto &w : word_count)
	cout<< w.first << " occurs " << w.second <<endl; 
  • 这里我们就能看到,first是key,second是value,对map的索引操作,即对value操作

  • map的初始化

  • 必须提供关键字key类型和值value类型: map<key, value> map_name;

  • 值可以改变,但是关键字不行

  • 插入

  • 在对map进行insert时,必须记住其元素类型是pair的,但是并没有现成的pair对象。因此我们在插入时创建一个pair,如下:

word_count.insert({word, 1});
word_count.insert(make_pair(word, 1));
word_count.insert(pair<string, size_t> (word, 1));
word_count.insert(map<string, size_t>::value_type(word, 1));

  • set的使用
  • set的主要意义在与快速查询元素是否存在。
  • set的关键字是不能改变的
  • 其迭代器是const
  • insert 操作
  • 返回值:pair类型
  • 如果key不是重复元素,插入成功,pair.first指具有给定关键字的元素,pair.second = true;
  • 如果是key重复元素,则什么也不做,pair.first指向具有给定关键字的元素,pair.second =false;
  • 对于multiset/multimap来说,不用考虑重复,因此first返回指向新元素的迭代器,无需返回bool值。
vector<string> vec = {"the", "but", "and", "or", "an"}; 
set<string> set2;
set2.insert({"a", "of"});//列表插入
set2.insert(vec.cbegin(), vec.cend());//迭代器插入

关联容器概述

  • 关联容器,适用于顺序容器中的:初始化,赋值,插入,删除,clear等
  • 正常的map和set内,关键字必须是唯一的,即每一个value和key都是一一对应的。
  • multimap,multiset内可以允许多个元素有相同的关键字,即一个key对应多个value。可以理解为一个词语(key)有多重释义(value)
  • 如果在给set,map进行赋值时,出现了重复的,则会自动默认不添加重复元素

  • pair,可以理解为是map的元素类型 key-value
  • 两个元素
  • 在这里插入图片描述

  • 删除erase
代码 操作/意义
c.erase(k) 从c中删除每个关键字为k的元素,返回一个size_type值,指出删除元素的数量
c.erase§ 从c中删除迭代器p指定的元素,p必须指向c中一个真实元素,返回p之后元素的迭代器
c.erase(b, e) 删除迭代器b-e所表示范围中的元素,返回e

  • map的下标操作
  • word_count[“anna”] = 1;
  • 查找关键字anna,如果存在,就将其value赋值1;
  • 如果不存在就将关键字anna插入到word_count中,并将value赋值为1。
  • 因为可能存在插入操作,因此,我们只可以对于一个非const的map进行下标操作

  • 访问容器
  • 对于需要计数元素的,就使用c.count();
  • 对于只需要判断是否存在的元素,就使用c.find();
  • c.lower_bound(k) —返回一个迭代器,指向第一个关键字不小于k的元素
  • c.upper_bound(k)—返回一个迭代器,指向第一个关键字不大于k的元素
  • c.equal_range(k)— 返回一个pair,两个迭代器iter1,iter2。如果存在多个和k关键字相等的元素,则iter1指向第一个k,iter2指向最后一个k。如果不存在,则两个迭代器均等于c.end()。

  • 无序容器
  • 在某些情况下,维护元素的序列代价非常高昂,此时无序容器很有用
  • unordered_map<string, size_t> word_count; //这就是无序容器
  • 管理桶
  • 无序容器在存储上组织为一组桶,每个桶保存零个或多个元素。
  • 无序容器使用一个哈希函数将元素映射到桶。
  • 为了访问一个元素,容器首先计算元素的哈希值,它指出应该搜索哪个桶。
  • 容器将具有一个特定哈希值的所有元素都保存在相同的桶中。
  • 如果容器允许重复关键字,则所有具有相同关键字的元素也会在同一个桶中。因此无序容器的性能以来与哈心函数的质量和桶的数量和大小。
  • 对于相同的参数,哈希函数必须总是产生相同的结果。
  • 理想情况下,哈希函数还能将每个特定的值映射到唯一的桶。
  • 将不同关键字的元素映射到相同的桶也是允许的。
  • 当一个桶内保存多个元素时,需要顺序搜索这些元素来查找我们想要的哪个。
  • 计算一个元素的哈希值和在桶内搜索元素通常都是很快的操作。但是,如果一个桶中保存了很多元素,那么查找一个特定元素就需要大量比较操作

  • 无序容器管理操作
  • 这里的c是指的无序容器,桶是该容器中的
桶接口 操作/意义
c.bucket_count() 正在使用的桶数目
c.max_bucket_count() 容器能容纳的最多的桶的数量
c.bucket_size(n) 第n个桶中有多少个元素
c.bucket(key) 关键字为key的元素在哪个桶中
桶迭代 操作/意义
local_iterator 可用来访问桶中元素的迭代器类型
const_local_iterator 上者的const版本
c.begin(n), c.end(n) 桶n的首尾元素迭代器
c.cbegin(n), c.cend(n) 上述的const版本
  • 哈希策略
    在这里插入图片描述
  • 无序容器对关键字类型的要求
  • 没看懂

猜你喜欢

转载自blog.csdn.net/qq_38096989/article/details/88249109
今日推荐