1. 关联式容器
关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的 键值对, 在数据检索时比序列式容器效率更高。
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)
{}
};
3.map
set
:
4.set (K模型)
set使用介绍
set是标准模板库(STL)中的一种关联容器,它存储的元素是唯一的,并且按照特定的顺序(默认是升序)自动排序。
https://cplusplus.com/reference/set/set/?kw=set
注意:
1. set的模板参数列表
2. set的构造
3. set的迭代器
4. set的容量
5. set修改操作
#include <set>
void TestSet()
{
// 用数组array中的元素构造set
int array[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4,
6, 8, 0 };
set<int> s(array, array+sizeof(array)/sizeof(array[0]));
cout << s.size() << endl;
// 正向打印set中的元素,从打印结果中可以看出:set可去重
for (auto& e : s)
cout << e << " ";
cout << endl;
// 使用迭代器逆向打印set中的元素
for (auto it = s.rbegin(); it != s.rend(); ++it)
cout << *it << " ";
cout << endl;
// set中值为3的元素出现了几次
cout << s.count(3) << endl;
}
5.multiset
它允许存储具有相同值的元素,并且这些元素会根据特定的排序准则自动排序。与 set 容器不同,multiset 允许重复的元素值。
https://cplusplus.com/reference/set/multiset/?kw=multiset
6. map(KV模型)
https://cplusplus.com/reference/map/map/?kw=map
1. map的模板参数说明
2. map的构造
3. map的迭代器
4. map的容量与元素访问
1.着重讨论operator[]
问题:当key不在map中时,通过operator获取对应value时会发生什么问题?
pair<iterator, bool> ret = insert(key, V());
return ret.first->second;//这里返回的是value
5. map中元素的修改
#include <string>
#include <map>
void TestMap()
{
map<string, string> m;
// c++98 插入
m.insert(pair<string, string>("peach", "桃子"));
// c++11 插入
m.insert(make_pair("banan", "香蕉"));
// 借用operator[]向map中插入元素
/*
operator[]的原理是:
用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中
如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器
如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器
operator[]函数最后将insert返回值键值对中的value返回
*/
// 将<"apple", "">插入map中,插入成功,返回value的引用,将“苹果”赋值给该引
用结果,
m["apple"] = "苹果";
cout << m.size() << endl;
// 用迭代器去遍历map中的元素,可以得到一个按照key排序的序列
for (auto& e : m)
cout << e.first << "--->" << e.second << endl;
cout << endl;
// map中的键值对key一定是唯一的,如果key存在将插入失败
auto ret = m.insert(make_pair("peach", "桃色"));
if (ret.second)
cout << "<peach, 桃色>不在map中, 已经插入" << endl;
else
cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
<< ret.first->second <<" 插入失败"<< endl;
// 删除key为"apple"的元素
m.erase("apple");
if (1 == m.count("apple"))
cout << "apple还在" << endl;
else
cout << "apple被吃了" << endl;
}
7. multimap
https://cplusplus.com/reference/map/multimap/?kw=multimap
8.实际应用
1.前k个高频单词
. - 力扣(LeetCode)
class Solution {
public:
struct compare
{
bool operator()(const pair<string,int> V1,const pair<string,int> V2)
{
return (V1.second > V2.second) || (V1.second == V2.second && V1.first < V2.first);//如果一样就按first排序
}
};//!!!!!!!!!!!!!!!!!!!!!!!!
vector<string> topKFrequent(vector<string>& words, int k) {
map<string,int> CountMap;
for(auto& e : words)
{
CountMap[e]++;//这里并没有有序,因为map的默认构造是根据key的大小进行排序插入的,但本题的要求是先按value降序排序,若相同再按key升序排序
}
vector<pair<string,int>> v(CountMap.begin(),CountMap.end()); //需要存到vector内才能调用sort函数因为迭代器类型不同
sort(v.begin(),v.end(),compare());//这里传的是compare对象,不是模板参数,sort支持仿函数
//如果不写compare直接调用会出问题,一是迭代器类型不匹配,
vector<string> vs;
for(size_t i=0; i<k;i++)
{
vs.push_back(v[i].first);
}
return vs;
}
};
仿函数往期连接:priority移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——8.stack&&queue&&priority_queue(模拟实现)-CSDN博客
2.两个数组的交集
. - 力扣(LeetCode)
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
set<int>arr(nums1.begin(),nums1.end());
set<int>brr(nums2.begin(),nums2.end());
vector<int> str;
int num=0;
auto it1=arr.begin();
auto it2=brr.begin();
while(it1!=arr.end()&&it2!=brr.end())
{
if(*it1!=*it2)
{
if(*it1<*it2)
it1++;
else
it2++;
}
else
{
str.push_back(*it1);
it1++;
it2++;
}
}
return str;
}
};
map和set对比
综上所述map和set很相似,很多接口都一样,区别如下