关联容器

  • set:唯一键的集合,按照键排序
  • map,按照键排序,键是唯一
  • multiset,按照键排序
  • multimap,按照键排序

set

set是关联容器,含有key类型对象的已排序集,用比较函数(compare)进行排序。搜索,移除和插入拥有对数复杂度,set通常以红黑树实现

迭代器

  • begin/cbegin : 返回指向起始的迭代器
  • end/cend : 返回指向末位的迭代器
  • rbegin/crbegin :返回指向起始的逆向迭代器
  • rend/crend : 返回指向末尾的逆向迭代器

容器

  • empty
  • size
  • max_size:返回可容纳的最大元素数
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;

int main(void)
{
	//创建关联容器set
	set<int> s{ 1,2,3,4,5,6 };
	//使用set的迭代器,循环遍历
	for_each(s.cbegin(), s.cend(), [](int x) { cout << x << " "; });
	cout << endl;
	//让bool显示未true或false
	cout << boolalpha;
	s.empty();
	cout << "s是否为空:" << s.empty() << endl;
	cout << "s的元素个数:" << s.size() << endl;
	cout << "s可理论容纳的最大数量:" << s.max_size() << endl;
	cout << endl;
	//清除s内容
	s.clear();
	cout << "清除后s是否为空:" << s.empty() << endl;
	//插入元素
	s.insert(s.begin(), 99);
	for_each(s.cbegin(), s.cend(), [](int x) { cout << x << " "; });
	cout << endl;
	return 0;
}
/*
1 2 3 4 5 6
s是否为空:false
s的元素个数:6
s可理论容纳的最大数量:576460752303423487

清除后s是否为空:true
99
*/

修改器

  • clear
  • insert:插入元素或结点C++17
  • emplace
  • emplace_hint
  • erase
    • 参数:
    • pos
    • first,last:要移除的元素范围
    • key:要移除的元素键值
    • x,自带要移除的元素
#include <iostream>
#include <set>
using namespace std;

int main(void)
{
	set<int> c = { 1,2,3,4,1,2,3,4 };
	auto print = [&c]
	{
		cout << "c={";
		for (int n : c)
		{
			cout << n << " ";
		}
		cout <<"}"<< endl;
	};
	print();
	cout << "移除所有奇数:" << endl;
	for (auto it = c.begin(); it != c.end();)
	{
		if (*it % 2 != 0)
		{
			//擦除首元素
			it = c.erase(it);
		}
		else
		{
			++it;
		}
	}
	print();
	cout << "移除1,移除个数" << c.erase(1) << endl;
	cout << "移除2,移除个数" << c.erase(2) << endl;
	cout << "移除2,移除个数" << c.erase(2) << endl;
	print();
	return 0;
}
/*
c={1 2 3 4 }
移除所有奇数:
c={2 4 }
移除1,移除个数0
移除2,移除个数1
移除2,移除个数0
c={4 }
*/
  • swap
  • extractC++17

解链含position所指向的结点并返回占有它的结点柄
若容器拥有元素而其关键等于x,则从容器解链该元素并返回占有它的结点柄,否则返回空结点柄
参数:
* position
* k
* x,鉴别要释放的结点
extractset带走仅移动对象的唯一方式

#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
int main(void)
{
	set<int> cont{ 1,2,3 };
	auto print = [](const int& n) { cout << " " << n; };
	for_each(cont.begin(), cont.end(), print);
	cout << endl;
	//C++17.解链含position所指向元素的结点柄返回占有它的结点柄
	auto nh = cont.extract(1);
	//对结点柄重新赋值
	nh.value() = 4;
	
	for_each(cont.begin(), cont.end(), print);
	cout << endl;
	//将nh结点柄插入尾部
	cont.insert(move(nh));

	for_each(cont.begin(), cont.end(), print);
	cout << endl;
}
/*
 1 2 3
 2 3
 2 3 4
*/
  • mergeC++17
#include <iostream>
#include <set>
using namespace std;

template <class Os,class K>
Os& operator<<(Os& os, const std::set<K>& v)
{
	//求出set的大小
	os << '[' << v.size() << "] {";
	bool o{};
	for (const auto& e : v)
	{
		//判断是否为空决定是,还是空
		os << (o ? ", " : (o = 1, " ")) << e;
	}
	return os << " }\n";
}
int main(void)
{
	set<char> 
		p{'C','B','B','A' },
		q{ 'E','D','E','C' };
	cout << "p: " << p << "q: " << q;
	//对set进行合并
	p.merge(q);
	//合并自动去重
	//q留下重复的部分
	cout << "p.merge(q):" << p << "q: " << q;

}
/*
p: [3] { A, B, C }
q: [3] { C, D, E }
p.merge(q):[5] { A, B, C, D, E }
q: [1] { C }
*/

查找

  • count
  • find
  • contains:检查容器是否含有带特定键的元素
  • equal_range
  • lower_bound
  • upper_bound

观察器

  • key_comp
  • value_comp:返回用于在value_type类型的对象中比较键的函数

multiset

multiset是含有key类型对象有序集的容器,与set不同,它允许多个key拥有等价的值,用关键比较函数Compare进行排序,搜索,插入和移除操作拥有对数复杂度
其用法与set相同

map

有序键值队容器,它的元素的键是惟一的。

元素访问

  • at,同时进行越界检查
  • operator[]
#include <iostream>
#include <map>
#include <string>
using namespace std;
//输出键值队map
auto print = [](auto const comment, auto const& map)
{
	cout << comment << "{";
	for (const auto& pair : map)
	{
		cout << "{" << pair.first << ":" << pair.second << "}";
	}
	cout << endl;
};

int main()
{
	map<char,int> letter_counts { {'a',27},{'b',3},{'c',1} };
	print("letter_counts初始状态下包含:", letter_counts);

	letter_counts['b'] = 42;
	letter_counts['x'] = 9;
	print("修改后的值", letter_counts);

	//统计每个单词出现的次数
	map<string, int> word_map;
	for (const auto& w : { "this","sentence","is","not","a","sentence","this","sentence","is","a","hoax" })
	{
		++word_map[w];
	}
	word_map["that"]; //插入对{"that",0}

	print("输出map:",word_map);
	
}

迭代器

  • begin/cbegin:返回指向起始的迭代器
  • end/cend
  • rbegin/crbegin
  • rend/crend

容器

  • empty
  • size
  • max_size

修改器

  • clear
  • insert
  • insert_or_assign,或若键已存在赋值给当前元素
  • emplace
  • emplace_hint:使用提示原位构造元素
  • try_emplace,若键存在则不做任何事情
  • erase
  • swap
  • extract:从另一个容器释出结点
  • merge

查找

  • count
  • find
  • contains
  • equal_range
  • lower_bound
  • upper_bound

观察器

  • key_comp
  • value_comp
#include <iostream>
#include <map>
#include <string>
using namespace std;
//输出键值队map
auto print_map = [](auto const comment, map<string,int>&map)
{
	cout << comment ;
	//C++11方案
	for (const auto& pair : map)
	{
		cout << "{" << pair.first << ":" << pair.second << "}";
	}
	
	
	cout << endl;
};

int main()
{
	map<string, int> m{ {"cpu",10},{"GPU",15},{"RAM",20} };
	print_map("初始map:", m);
	//以不存在的键执行插入操作
	m["SSD"] = 30;
	print_map("插入不存在的:", m);
	//移除GPU
	m.erase("GPU");
	print_map("移除后:", m);
	//条件移除
	erase_if(m, [](const auto& pair) { return pair.second > 25; });
	print_map("条件移除后:", m);
	cout << m.size() << endl;

	m.clear();
	cout << boolalpha << "m是否为空:" << m.empty() << endl;
	return 0;
}
/*
初始map:{GPU:15}{RAM:20}{cpu:10}
插入不存在的:{GPU:15}{RAM:20}{SSD:30}{cpu:10}
移除后:{RAM:20}{SSD:30}{cpu:10}
条件移除后:{RAM:20}{cpu:10}
2
m是否为空:true

*/

multimap

含有键值队的已排序列表,同时容纳许多个元素拥有同一键。与map用法相同

无序关联容器

在内部,元素不以任何特别顺序排序,而是组织进桶中。元素被放进哪个桶完全依赖其值的哈希,这允许对单独元素的快速访问,因为哈希一旦确定,就准确自带元素被放入的桶。不可修改容器元素(即使通过非cons迭代器),因为修改更改元素的哈希,并破坏容器

  • unordered_set,按照键生成散列
  • unordered_map,按照键生成散列,是唯一的
  • unordered_multiset: 键的集合,按照键生成散列
  • unordered_multimap:键值队的集合,按照键生成散列

unordered_set

含有key类型的唯一对象集合关联容器

迭代器

  • begin/cbegin
  • end/cend

容器

  • empty:检查容器是否为空
  • size:返回容纳的元素数
  • max_size:返回可容纳的最大元素数

修改器

  • clear
  • insert或结点C++17
  • emplace
  • emplace_hint
  • erase
  • swap:交换内容
  • extract:从另一容器释出结点
  • merge

查找

  • count:返回匹配特定键的元素数量
  • find:寻找带有特定键的元素
  • contains
  • equal_range:返回匹配特定键的元素范围

桶接口

  • begin(size_type)/cbegin(size_type):返回一个迭代器,指向指定的桶的开始:返回指向下标为n的桶首元素的迭代器
  • end(size_type)/cend(size_type),。返回后随下标为n的桶的最后元素的元素的迭代器,此元素表现为占位符,试图访问它会导致未定义行为
  • bucket_count
  • max_bucket_count
  • bucket_size:返回在特定的桶中的元素数量
  • bucket,key

哈希策略

  • load_factor:返回每个容的平均元素数量
  • max_load_factor:管理每个容的平均数量的最大值
  • rehash:为至少为指定数量的桶预留存储空间并重新生成散列表
  • reserve

观察器

  • hash_function
  • key_eq

unordered_multiset

含有可能非唯一key类型对象的集合

unordered_map

含有唯一键-值 pair

迭代器

  • begin/cbegin
  • end/cend

容器

  • empty:检查容器是否为空
  • size:返回容纳的元素数
  • max_size:返回可容纳的最大元素数

修改器

  • clear
  • insert或结点C++17
  • emplace
  • emplace_hint
  • erase
  • swap:交换内容
  • extract:从另一容器释出结点
  • merge

查找

  • at:访问指定的元素,同时进行越界检查
  • operator[]
  • count:返回匹配特定键的元素数量
  • find:寻找带有特定键的元素
  • contains``C++20
  • equal_range:返回匹配特定键的元素范围

桶接口

  • begin(size_type)/cbegin(size_type):返回一个迭代器,指向指定的桶的开始:返回指向下标为n的桶首元素的迭代器
  • end(size_type)/cend(size_type),。返回后随下标为n的桶的最后元素的元素的迭代器,此元素表现为占位符,试图访问它会导致未定义行为
  • bucket_count
  • max_bucket_count
  • bucket_size:返回在特定的桶中的元素数量
  • bucket,key

哈希策略

  • load_factor:返回每个容的平均元素数量
  • max_load_factor:管理每个容的平均数量的最大值
  • rehash:为至少为指定数量的桶预留存储空间并重新生成散列表
  • reserve

观察器

  • hash_function键散列的函数
  • key_eq

unordered_multimap

支持等价的键(一个unordered_multimap可含有每个键值的多个副本)和将键与另一个类型的值关联

迭代器

  • begin/cbegin
  • end/cend

容器

  • empty:检查容器是否为空
  • size:返回容纳的元素数
  • max_size:返回可容纳的最大元素数

修改器

  • clear
  • insert或结点C++17
  • emplace
  • emplace_hint
  • erase
  • swap:交换内容
  • extract:从另一容器释出结点
  • merge

查找

  • count:返回匹配特定键的元素数量
  • find:寻找带有特定键的元素
  • contains``C++20
  • equal_range:返回匹配特定键的元素范围

桶接口

  • begin(size_type)/cbegin(size_type):返回一个迭代器,指向指定的桶的开始:返回指向下标为n的桶首元素的迭代器
  • end(size_type)/cend(size_type),。返回后随下标为n的桶的最后元素的元素的迭代器,此元素表现为占位符,试图访问它会导致未定义行为
  • bucket_count
  • max_bucket_count最大桶数
  • bucket_size:返回在特定的桶中的元素数量
  • bucketkey检验键值

哈希策略

  • load_factor:返回每个容的平均元素数量
  • max_load_factor:管理每个容的平均数量的最大值
  • rehash:为至少为指定数量的桶预留存储空间并重新生成散列表
  • reserve

观察器

  • hash_function
  • key_eq