目录
- 一. 键值对
- 1. 关联式容器
- 2. pair
- 3. 应用场景
- 二. set
- 1. set的介绍
- 2. set的使用
- 3. multiset的介绍
- 三. map
- 1. map的介绍
- 2. map的使用
- 3. multimap的介绍
一. 键值对
用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value。key代表键值,value表示与key对应的信息
1. 关联式容器
- 序列式容器:如vector、list等,其底层为线性序列的结构,存储的数据是元素本身
- 关联式容器:存储的是<key, value>的键值对,利于进行数据检索。
2. pair
在库中已经实现好的结构,SGI-STL中关于键值对的定义:
template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair()
: first(T1())
, second(T2())
{}
pair(const T1& a, const T2& b)
: first(a)
, second(b)
{}
};
其含有两个成员对象,first对应key、second对应value
库中定义了make_pair()函数,可以方便创建pair对象,该函数模板会根据传入参数类型进行自动隐式推导,构造并返回一个的pair对象。
template <class T1, class T2>
pair<T1, T2> make_pair(T1 x, T2 y)
{
return (pair<T1, T2>(x, y));
}
3. 应用场景
- 树型结构:如map、set、multimap、multiset,使用红黑树作为底层结构。
- 哈希结构:如unordered_set、unordered_map,使用哈希表作为底层结构。
二. set
1. set的介绍
set使用文档
T:set中存放的元素类型,
Compare:set元素的比较方式,默认按小于来比较
Alloc:set元素空间的管理方式,使用STL提供的空间配置器管理
- set是按照一定次序存储元素的容器,元素按照其比较对象(class Compare)所规定的规则进行排序
- 默认按照小于(less< T>)来进行比较,迭代遍历,可以得到有序序列。
- 在set中,元素的value(类型为T)是唯一的,不会重复。不能修改value,但是可以从容器中删除再插入
- set元素中数据value只有一个类型T,但其底层实际存放的是由<value, value>构成的键值对(底层由红黑树实现)
2. set的使用
void testSet()
{
int a[] = { 1,2,3,4,2023,1,9,3,50 };
int size = sizeof(a) / sizeof(a[0]);
//排序+去重
set<int> s(a, a + size);
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
s.erase(9);
s.erase(2023);
for (int i = 0; i < size; ++i)
{
if (s.find(a[i]) == s.end())//没找到返回s.end()
{
cout << a[i] << " 被删除了" << endl;
}
}
}
3. multiset的介绍
multiset使用文档
与set基本一样,其中区别在于:multiset容器中允许重复元素存在
void testSet()
{
int a[] = { 1,2,3,4,2023,1,9,3,50 };
int size = sizeof(a) / sizeof(a[0]);
//排序+不去重
multiset<int> s(a, a + size);
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
}
三. map
1. map的介绍
map使用文档
key:键值对中key的类型
T:键值对中value的类型
Compare:比较对象,默认按照元素中的key的小于进行比较
Alloc:使用STL提供的空间配置器管理
- map中元素是键值对,其中key是唯一的,不能重复,不能修改
- 用迭代器遍历,可以得到一个有序序列
- 支持"[]"下标访问操作符,在[]中放入key,就可以访问对应的value
2. map的使用
void testMap()
{
string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
map<string, int> countMap;
for (auto& str : arr)
{
map<string, int>::iterator it = countMap.find(str);
if (it != countMap.end())
{
//(*it).second++;
it->second++;
}
else
{
countMap.insert(make_pair(str, 1));
}
}
//for (auto& str : arr)
//{
// // 1、str不在countMap中,插入pair(str, int()),然后在对返回次数++
// // 2、str在countMap中,返回value(次数)的引用,次数++;
// countMap[str]++;
//}
map<string, int>::iterator it = countMap.begin();
while (it != countMap.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
}
3. multimap的介绍
multimap使用文档
multimap和map也相似,不同点:multimap中的Key是可以重复的;没有operator[],因为key可能对应多个value。