map和set
1. 什么关联式容器?
在C++中,容器大致分为2类。分别是序列式容器和关联式容器。其中,序列式容器有vector、list、deque以及C++11中的forward。序列式容器的底层是线性序列的数据结构,里面存储的是元素本身。例如:
vector<int> V;//这里就说明,声明了一个int类型的数组,里面存放的是int类型的值
而关联式容器虽然也是用来存放数据,但是这里面存储的是<key,value>结构的键值对。同时map、set、multimap、multiset也称为树形结构的关联式容器,因为它们的底层为RB树。
例如
map<string,int> m;
2.键值对
键值对一般包含两个成员key和vaule。key代表键值,value代表与key对应的信息。就比如一个英汉词典,insert:插入。其中insert代表key,插入代表value。
在STL源码中,对键值对的定义是
//struct代表public
template<class T1,class T2>
struct pair{
typedef T1 first_type;
typedef T2 second_type;
T1 frist;
T2 second;
//实现构造函数
pair()
:first(T1())
,second(T2())
{}
//实现拷贝构造
pair(const T1& a, const T2& b)
:first(a)
,second(b)
{}
};
//s中存储的就是键值对
vector<pair<int,string>> s;
3.set
1、set的模板参数列表
template < class T,
class Compare = less<T>,
class Alloc = allocator<T>
> class set;
T:存放的是元素类型。
compare:仿函数,缺省值为less,也可以选择greater
alloc:为空间配置器。
2、set的构造
3.set的修改操作
函数 | 返回值 |
---|---|
pair<iterator,bool> insert (const value_type& val); | 返回值为pair<iterator,bool>,如果插入成功返回<插入位置,true>,插入失败返回<插入失败的位置,false> |
void erase ( iterator position ) | 删除位置为position的值 |
size_type erase ( const key_type& x ) | 删除值为x的元素 |
void erase ( iterator first, iterator last) | 删除迭代区间的元素 |
iterator find ( const key_type& x ) const | 找到值为x的位置,如果成功者返回其x所属位置的迭代器。 |
4.map
1.map的特点
- 按照key的次序存储,由key和value组合
- 通过value_type绑定 typedef value_type pair --> pair<key,value>
- map中的元素按照key来排序
- map支持operator [] ,即支持跟数组类似的访问方式
- map中的元素如果用迭代器去遍历,会得到一个有序的序列
2.map的模板参数列表
template < class Key, // map::key_type
class T,// map::mapped_type
class Compare = less<Key>, // map::key_compare
class Alloc = allocator<pair<const Key,T> > //map::allocator_type > class map;
compare中一般按照key来比较大小
3.map的操作
函数 | 返回值 |
---|---|
pair<iterator,bool> insert ( const value_type& x ) | 在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入元素的位置,bool代表释放插入成功 |
mapped_type& operator[] (const key_type& k) | 如果找到k,则返回其key对应的value。若找不到则完成insert |
operator[] <key,T()>
5、相关的OJ题目
- 单词识别
题解:1、首先使用getline函数接受输入
2、按照空格切分每个字符串。并统一转成小写
3、将每个字符串存入map中。
4、输出
参考代码如下:
#include <iostream>
#include<string>
#include<map>
using namespace std;
int main() {
string s;
getline(cin, s);
map<string, int> m;
int i = 0;
while (i < s.size() - 1)
{
string str;
while ( i < s.size() - 1 && s[i] != ' ')
{
s[i] = tolower(s[i]);
str += s[i];
i++;
}
i++;
m[str]++;
}
auto it = m.begin();
while (it != m.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
return 0;
}
- 前K个高频词
解题思路:1、使用map存储数据
2、如果直接调用sort,会出现问题,sort属于快排,不稳定
3、使用multimap<int,string,greater>
代码如下:
class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k) {
map<string,int> m;//定义一个map用来记录
for(auto& e:words)
{
++m[e];//operator[]
}
//2.对value进行排序,如果使用sort但是会失败,因为sort的底层是快排,稳定性不好,意思就是不能按字母进行排序。
multimap<int,string,greater<int>> mm;//定义一个multimap进行记录,允许冗余key
//或者再这里multimap<int,string,greater<int>> mm;
for(auto ee:m)
{
mm.insert(make_pair(ee.second,ee.first));//将map中的数据插入到mm中,更改key和value
}
vector<string> ret;
auto mmm=mm.begin();
// multimap<int,string>::reverse_iterator mmm=mm.rbegin();
while(k--)
{
ret.push_back(mmm->second);
++mmm;
}
return ret;
}
};