第11章 关联容器

map,管理数组,存储“关键字-值”

set,简单集合,存储“关键字”

四个关联容器的头文件map、set、unordered_map、unordered_set

关联容器有8种,特点如下:

  1. 每个容器都是set或者map
  2. 分为允许关键字重复(multi)和不允许关键字重复
  3. 顺序保存和无序保存(unordered,哈希函数组织的结构)

unordered_multiset是一个允许关键字重复,元素无序保存的集合

set是一个要求关键字不重复,元素有序保存的集合

map<string, size_t> word_count; 
set<string> include = {"a" "e" "i" "o" "u"};
string word;
while (cin >> word)
{
    if (include.find(word) == include.end())
        word_count[word]++;//如果容器中没有,会自动创建一个新元素
}
for (auto &w : word_count)
{
    cout << w.first << "	" << w.second << endl;
}

11.1有序容器要求

对于有序容器,关键字满足以下之一才能定义

  1. 需要定义”<”操作符,推荐定义的操作符严格弱化(strict weak ordering,如下英文版截图的解释,中文版将less than译作小于等于,可能是不正确的)。
  2. 指定比较函数
class Book
{
public:
string s; };
bool compare_book(const Book &b1, const Book &b2) { return b1.s < b2.s; } int main() { map<Book, int, decltype(compare_book)*> m(compare_book); set<Book, decltype(compare_book)*> s(compare_book); }

使用关联容器,定义时需要指明类型,所以使用decltype获得函数类型,由于此处传入的函数指针类型,所以需要最后使用*号,并在初试化时传入函数作为参数。

pair类型定义在utility头文件中

string key("123");
int value = 155;
pair<string, int> p;
pair<string, int> p1(key, value);
pair<string, int> p2 = { key, value };
auto p3 = make_pair(key, value);
cout << p.first << p.second;

 

隐式构造返回值

return pair<string, int>();

11.2关联容器操作

提取相关类型

set<string>::value_type v1;  // v1 is a string
set<string>::key_type v2;  // v2 is a string
map<string, int>::value_type v3; // v3 is a pair<const string, int>
map<string, int>::key_type v4;  // v4 is a string
map<string, int>::mapped_type v5; // v5 is an int

 

迭代器

// 得到首迭代器
auto map_it = word_count.begin();
// pair<const string, size_t>
map_it->first = "new key";  // 不能改: key是const
++map_it->second;  // 可以改

对关联容器使用的算法

通用算法对于关联容器的使用总是坏的,使用关联容器的find比泛型find快的多。

对关联容器使用算法,要么让其作为原序列(例如拷贝出去),要么当成目的位置(插入进去)。

关联容器操作

.find
.insert       (.emplace)
.erase
.find
.count
//因为迭代器中的元素按顺序排列,所以下边两个可以得到一个范围
.lower_bound
.upper_bound
//可用下边方法替换,返回的pair中包含两个迭代器
.equal_range
for (auto beg = authors.lower_bound(search_item),
    end = authors.upper_bound(search_item);
    beg != end; ++beg)
    cout << beg->second << endl;
等价于
for (auto pos = authors.equal_range(search_item);
    pos.first != pos.second; ++pos.first)
    cout << pos.first->second << endl;

11.3无序容器

无序容器使用哈希函数和符号”==”来组织元素

使用hash<key_type>类型的 西乡来生成每个元素的哈希值

哈希方法在于,每一个key通过哈希算法,映射到一个桶(bucket中,不同的key也可能映射到相同的桶中。

管理桶

c.bucket_count()//使用中的桶的数目
c.max_bucket_count()//容器最多容纳多少桶
c.bucket_size(n)//第n个桶有多少元素
c.bucket(k)//关键字为k的桶在的位置

local_iterator//桶中元素的迭代器类型
const_local_iterator
c.begin(n)    c.end(n)    c.cbegin(n)    c.cend(n)

c.load_factor()//桶中平均元素数量float
c.max_load_factor()//试图维护的平均元素数量,c会在需要时添加新桶,是的上值小于此值
c.rehash(n)//从组存储,使得增加桶数量>n

无序容器对关键字的要求

  1. 具有==操作
  2. 指定hasher
  3. 或者,自定义类如果要使用无序容器,必须提供自己的hash模板特例化版本。
原文地址:https://www.cnblogs.com/qiusuo/p/4992812.html