C++ 笔记:关联容器

关联容器概述

  • 顺序容器中的元素按其在容器中的顺序保存和访问,而关联容器中的元素则按关键字保存和访问

关联容器类型

map

  • key - value 映射的集合,关键字不允许重复,且有序排列
  • #include
  • 使用例子:
string word;
map<string, size_t> word_count;   // 一个从字符串到计数的空 map
                                  // 要定义一个 map,必须同时提供 key 和 value 的类型
while (cin >> word)
  ++word_count[word];             // 通过下标运算符将 word 的计数器加 1
                                  // 如果 key 不在当前 map 中,下标运算符会创建一个新映射
for (const auto wc : word_count)  // wc 的实际类型为 pair
  cout << wc.first << " occurs " << wc.second 
       << ((wc.second > 1) ? "times" : "time") << endl;
  // wc.first 指向当前映射 wc 中的 key,wc.second 指向当前映射 wc 中的 value

multimap

  • key - value 映射的集合,关键字允许重复,且有序排列
  • #include

unordered_map

  • key - value 映射的集合,关键字不允许重复,无序排列
  • #include

unordered_multimap

  • #include

  • key - value 映射的集合,关键字允许重复,无序排列

set

  • key 的集合,关键字不允许重复,且有序排列
  • #include
  • 使用例子:
string word;
map<string, size_t> word_count;
set<string> exclude_articles = {"a", "an", "the", "A", "An", "The"};  // 需要剔除的冠词
while (cin >> word)
  if (exclude_articles.find(word) == exclude_articles.end())  // 只统计不在 set 中的单词
    // find(key) 返回一个迭代器,若 key 在 set 中,则返回指向 key 的迭代器,否则返回尾后迭代器
    ++word_count[word];

multiset

  • key 的集合,关键字允许重复,且有序排列
  • #include

unordered_set

  • key 的集合,关键字不允许重复,无序排列
  • #include

unordered_multiset

  • key 的集合,关键字允许重复,无序排列
  • #include

关键字类型

  • 对于有序容器,关键字类型必须定义了元素之间比较的方法

使用自定义的关键字比较操作

  • 为了使用自定义的操作,必须在定义关联容器时同时提供关键字类型和比较操作的类型 —— 一种函数指针类型,指向自定义的比较函数
bool compare(const string & str1, const string & str2) {
  return str1.size() < str2.size();
}

set<string> exclude1 = {"a", "an", "the", "A", "An", "The"};
set<string, decltype(compare)*> exclude2(compare) = exclude1;

pair 类型

  • #include
  • 一个 pair 包含两个 public 的数据成员,分别命名为 firstsecond
  • map 的每个元素都是一个 pair

关联容器操作

类型别名

  • key_type:关键字类型
  • mapped_typemap 中值的类型
  • value_type:对于 set,与 key_type 相同;对于 map,为 pair

迭代器

  • 解引用一个迭代器返回一个 value_type 类型的引用
  • mapset 的关键字都是 const 的,不允许修改,因此迭代器也是 const_iterator 类型
  • map 中的 value 可以修改
auto map_it = word_count.begin();   // map_it 的类型为 &pair
cout << map_it->first << " " << map_it->second;
map_it->first = "new key";          // ERROR! 
++map_it->second;                 

添加元素:insert()

mapset 添加元素

  • 必须以 pair 的形式向 map 添加元素:
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));
  • 对于不包含重复元素的关联容器,insert() 返回一个 pairpairfirst 成员是指向具有给定关键字的元素,second 是一个 bool 值,指出元素是插入成功还是已经存在于容器中。如果元素已经存在于容器中,secondfalse,否则为 true

multimapmultiset 添加元素

multimap<string, string> player;
player.insert({"LeBron James", "Cleveland Cavaliers"});
player.insert({"LeBron James", "Miami Heat"});
player.insert({"LeBron James", "Los Angeles Lakers"});
player.insert({"Dwayne Wade", "Cleveland Cavaliers"});
player.insert({"Dwayne Wade", "Miami Heat"});
player.insert({"Dwayne Wade", "Chicago Bulls"});
  • 对于允许重复关键字的容器,insert() 操作总是成功,并返回一个指向新元素的迭代器

删除元素:erase()

  • erase(key):删除所有关键字为 key 的元素,返回被删除元素的个数

  • erase(iter):删除迭代器 iter 指向的元素,iter 不能指向尾后元素;返回指向所删除元素之后的元素的迭代器

  • erase(begin, end):删除迭代器范围内的元素,返回 end

访问元素

mapunordered_map 的下标 []at():通过 key 获得 value

  • 下标运算符不支持 multimapunordered_multimap
  • 如果关键字不存在,则会创建一个元素并插入到 map 中,并对 value 值初始化
  • 由于下标运算符可能插入新元素,因此只能对非 constmap 使用下标
  • 对于 at(key),若 key 不存在,则抛出 out_of_range 异常
  • map 的下标返回 mapped_type 类型的对象(即值),且是一个左值

在关联容器中查找元素

  • find(key):返回一个迭代器,指向第一个关键字为 key 的元素;若不存在,则返回尾后迭代器
  • count(key):返回关键字为 key 的元素数量
  • lower_bound(key):返回一个迭代器,指向第一个关键字不小于 key 的元素
  • upper_bound(key):返回一个迭代器,指向第一个关键字大于 key 的元素
  • equal_range(key):返回一个迭代器 pair,第一个迭代器指向第一个关键字为 key 的元素,第二个迭代器指向最后一个关键字为 key 的元素之后的位置;若未找到,则两个迭代器都指向 end()

你可能感兴趣的:(C++)