20170611_常用关联容器的函数
1、关联容器支持快速的高效的关键字查找和访问。标准库提供了8个关联容器:
按照关键字有序保存元素:
- map:关联数组:保存“关键字—值”对。
- set:关键字即值,只保存关键字的容器。
- multimap:关键字可以重复出现的map。
- multiset:关键字可以重复出现的set。
无序集合:
- unordered_map:用哈希函数组织的map。
- unordered_set:用哈希函数组织的set。
- unordered_multimap:哈希组织的map,关键字可以重复出现。
- unordered_multiset:哈希组织的set,关键字可以重复出现。
2、map:关键字-值对的集合,也就是关联数组。该数组的下标是关键字,可以不必是正整数,可以通过关键字来O(1)的查找某个元素。
当从 map 中读取一个元素时,会得到一个pair 类型的对象,简单来说,pair 是一个模板类型,保存两个名为first 和second 的数据成员(都是公有的)。map 所保存的pair 用first 来保存关键字,second 来保存对应的值。
举例子:
//统计每个单词在输入中出现的次数。
map<string, size_t> word_count;
string word;
while(cin>>word)
++word_count[word];
for(const auto &mem:word_count)
cout<<mem.first<<" occurs "<<mem.second<<((mem.second > 1)?" times ":" time")<<endl;
3、set:关键字的简单集合。当只是想知道一个值是否存在时,set 是最好的选择。
举例子:
//忽略常见的单词,如“the”、“and”、“or”等。我们可以在set 保存想要忽略的单词,
//只对不在集合中出现的单词进行统计数目。
map<string, size_t> word_count;
set<string> exclude={"the","and","or","an","a"};
string word;
while(cin>>word)
{
if(exclude.find(word)==exclude.end())
++word_count[word];
}
4、pair 类型: #include<utility>
简单来说,pair 是一个模板类型,保存两个名为first 和second 的数据成员(都是公有的)。map 所保存的pair 用first 来保存关键字,second 来保存对应的值。
pair 上的操作:
- pair<T1, T2> p; //p 是一个pair,类型分别是T1和T2,进行了值初始化。
- pair<T1, T2> p(v1, v2); //p 是一个pair,类型分别是T1和T2,用v1 和v2 进行了初始化。
- pair<T1, T2> p={v1, v2}; //p 是一个pair,类型分别是T1和T2,用v1 和v2 进行了初始化。
- make_pair<v1, v2>; //返回一个用v1 和v2 进行了初始化的pair,pair 的类型是从v1 和v2 的类型推断出来
- p.first; //关键字
- p.second; //值
- p1 relop p2; //关系运算符
- p1 == p2;
- p1 != p2;
5、关联容器的操作:
- key_type: //关键字类型
- mapped_type: //值类型。只适用于map。
- value_type: //对于set:与key_type 一样。对于map:是 pair<key_type,mapped_type>。
6、解引用操作:
map:
//获得指向word_count 中一个元素的迭代器:
map<string, size_t> word_count;
auto map_it = word_count.begin(); //获得指向word_count 中第一个元素(元素是pair 类型)的迭代器。
cout<<map_it->first; //打印关键字。
couot<<map_it->second; //打印值。
map_it->first="new key"; //错误,关键字是const 类型的。
map_it->second++; //正确,可以通过迭代器来改变元素
记住:一个map 的value_type 是一个pair 类型,我们可以改变pair 的值,但是不能改变pair 的关键字。
set:
set<int> iset={0,1,2,3,4,5,6,7,8,9};
set<int>::iterator set_it=iset.begin();
if(set_it != iset.end())
{
*set_it=42; //错误,set 中的关键字是只读的。
cout<<*set_it<<endl; //正确,可以读取关键字。
}
7、遍历关联容器:
map 和set 都是支持迭代器的, begin()和 end()操作、cbegin()和 cend()。用它们可以遍历关联容器。
//获得指向word_count 中一个元素的迭代器:
map<string, size_t> word_count;
auto map_it = word_count.cbegin(); //获得指向word_count 中第一个元素(元素是pair 类型)的迭代器。
while(map_it != word_count.cend())
{
cout<<map_it-first<<","
<<map_it-second<<endl;
++map_it; //递增迭代器,使其指向下一个元素
}
8、添加元素:关联容器的insert 操作:
- c.insert( v ); //v 是value_type 类型的一个对象。
- c.emplace( args ); //args 用来构造一个对象。
- c.insert( b, e ); //b 和e 是迭代器,表示一个 c::value_type类型的范围。
- c.insert( p, v ); //类似于c.insert(v),在迭代器p 所指向元素的前面插入一个元素v。
9、删除元素:
- c.erase( k ); //从c 中删除关键字为k 的元素。返回一个size_type 值,指出删除的元素的个数。
- c.erase( p ); //从c 中删除迭代器p 指定的元素,p 必须指向c 中一个真实元素。
- c.erase( b, e ); //删除迭代器对b 和e 所表示的范围中的元素,返回e。
10、map 和 unordered_map 的下标操作:
- c[ k ]: 返回关键字为 k 的元素,如果 k 不在c 中,添加一个关键字为 k 的元素,对其进行初始化。
- c.at( k ): 访问关键字为 k 的元素,带参数检查:若 k 不在 c 中,则跑出一个异常“out_of_range”。
11、访问元素:在一个关联容器中寻找元素的操作。
- lower_bound 和 upper_bound 不适用于无序容器。
- 下标操作 和 at 操作只适用于非const 的map 和 unordered_map。
- c.find( k ); //返回一个迭代器,指向容器 c 中第一个关键字是 k 的元素,若 k 不在容器中,则返回尾后迭代器。
- c.count( k ); //返回关键字等于 k 的元素的数量。对于不允许重复关键字的容器,返回值永远是0或者1。
- c.lower_bound( k ); //返回一个迭代器,指向第一个关键字 不小于 k 的元素。
- c.upper_bound( k ); //返回一个迭代器,指向第一个关键字 大于 k 的元素。
- c.equal_range( k ); //返回一个迭代器pair,表示关键字等于 k 的元素的范围。若 k 不存在,pair 的两个成员均等于 c.end()。
12、无序容器管理操作:
桶接口:
- c.bucket_count(); //正在使用的桶的数目。
- c.max_bucket_count(); //容器能够容纳的最多的桶的数量。
- c.bucket_size( n ); //第 n 个桶中有多少个元素。
- c.bucket( k ); //关键字为 k 的元素在哪个桶中。
桶迭代:
- local_iterator(); //可以用来访问桶中元素的迭代器类型。
- const_local_iterator(); //桶迭代器的const版本。
- c.begin(); c.end(); //桶 n 的首元素迭代器和尾后迭代器。
- c.cbegin(); c.cend(); //与前两个函数类似,但返回的是 const 版本的 const_local_iterator()。
哈希策略:
- c.load_factor(); //每个桶的平均元素数量,返回float 值。
- c.max_load_factor(); //
- c.rehash( n ); //
- c.reserve( n ); //
另外:
map 是一种关联式容器,包含“ 关键字 / 值 ” 对。
1、 begin() 返回指向 map 头部的迭代器
2、 clear() 删除所有元素
3、 count() 返回指定元素出现的次数
4、 empty() 如果 map 为空则返回 true
5、 end() 返回指向 map 末尾的迭代器
6、 equal_range() 返回特殊条目的迭代器对
7、 erase() 删除一个元素
8、 find() 查找一个元素
9、 get_allocator() 返回 map 的配置器
10、insert() 插入元素
11、key_comp() 返回比较元素 key 的函数
12、lower_bound() 返回 键值 >= 给定元素 的第一个位置
13、max_size() 返回可以容纳的最大元素个数
14、rbegin() 返回一个指向 map 尾部的 逆向迭代器
15、rend() 返回一个指向 map 头部的 逆向迭代器
16、size() 返回 map 中元素的个数
17、swap() 交换两个 map
18、upper_bound() 返回 键值 > 给定元素 的第一个位置
19 、value_comp() 返回比较元素 value 的函数set 是集合,set 中不会包含重复的元素,这是和 vector 的区别。
1. begin() 返回指向第一个元素的迭代器
2. clear() 清除所有元素
3. count() 返回某个值元素的个数
4. empty() 如果集合为空,返回 true
5. end() 返回指向最后一个元素的迭代器
6. equal_range() 返回集合中与给定值相等的 上 下 限 的两个迭代器
7. erase() 删除集合中的元素
8. find() 返回一个指向被查找到元素的迭代器
9. get_allocator() 返回集合的分配器
10. insert() 在集合中插入元素
11. lower_bound() 返回指向 >= 某值的第一个元素的迭代器
12. key_comp() 返回一个用于元素间值比较的函数
13. max_size() 返回集合能容纳的元素的最大限值
14. rbegin() 返回指向集合中最后一个元素的反向迭代器
15. rend() 返回指向集合中第一个元素的反向迭代器
16. size() 集合中元素的数目
17. swap() 交换两个集合变量
18. upper_bound() 返回 > 某个值元素的迭代器
19. value_comp() 返回一个用于比较元素间的值的函数