1、键值对
用来表示具有一一对应关系的一种结构。
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)
{}
};
2、set
2.1 set特性
1)set中每个元素都是唯一的,且每个元素不能再容器中修改,但是可以插入或删除它们。
2)set在底层使用的是二叉搜索树(红黑树)实现的。
3)set中的元素不能重复(set有自动去重的功能)
4)set中查找某个元素的时间复杂度:O(logN)
2.2 set
1)set的参数列表
// std::set
template<class T, class Compare = less<T>, class Alloc = allocator<T>>
class set
Compare:默认小于的方式比较
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器
2)set的构造
// 使用(first, last)区间中的元素构造set
set(iterator first, iterator last);
3)set的迭代器
// 正向迭代器
iterator begin();
iterator end();
// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();
4)set的容量
bool empty()const;
size_t size() const;
5)修改操作
// 插入
pair<iterator, bool>insert(const T& val);
iterator insert(iterator pos, const T& data);
template<class T>
void insert(T first, T last);
// 删除
void erase(iterator pos);
size_t erase(const T& x); 删除值为x的元素,返回删除的个数
void erase(iterator first, iterator last);删除区间元素
// 交换
void swap(set& x);
// 清空
void clear();
6)operations
iterator find(const T& val) const;
size_t count(const T val)const;
7)set使用代码
#include <iostream>
#include <set>
void TestSet()
{
int array[] = { 1, 3, 5, 7, 4, 6, 8, , 4, 6, 8, 0 };
std::set<int> s(array, array+sizeof(array)/sizeof(array));
cout << s.size() << endl;
// 范围for遍历
for (auto& e : s)
cout << e << " ";
cout << endl;
// 使用迭代器逆向遍历
for (auto it = s.rbegin(); it != s.rend(); ++it)
cout << *it << " ";
cout << endl;
}
3、map
3.1 map特性
1)map是关联式容器,它按照一定次序存储键值对的元素。
2)map中按照key进行比较排序
3)可以使用 [] 访问
3.2 map
template < class Key,
class T,
class Compare = less<Key>,
class Alloc = allocator<pair<const Key,T>>>
class map;
1)map构造
std::map();
2)迭代器
iterator begin();
iterator end();
reverse_iterator rbegin();
reverse_iterator rend();
3)容量
bool empty() const;
size_type size() const;
4)元素访问
operator[];
at[]; //C++11
5)修改
// 插入
pair<iterator, bool>insert(const T& val);
iterator insert(iterator pos, const T& val);
template<class T>
void insert(T first, T last);
// 删除
void erase(iterator pos);
size_t erase(const T& k);
void erase(iterator fisrt, iterator last);
// 交换
void swap(map& x);
// 清空
void clear();
6)operations
// 查找
iterator find(const T& k);
size_t count(const T& k) const;
7)map的使用代码
#include <iostream>
#include <string>
#include <map>
void TestMap()
{
std::map<string, string> m;
m.insert(std::pair<string, string>("dad", "爸爸"));
m.insert(std::make_pair("mother", "妈妈"));
m["son"] = "儿子";
std::cout << m.size() << std::endl;
for (auto& e : m)
std::cout << e.first << "-->" << e.second << std::endl;
std::cout << endl;
auto ret = m.insert(std::make_pair("sister", "姐姐"));
if (ret.second)
cout << "sister已经插入" << endl;
else
cout << "sister元素已经存在:" << ret.first->first << "-->" <<ret.first->second <<" 插入失败"<< endl;
m.erase("son");
if (1 == m.count("son"))
cout << "son还在" << endl;
else
cout << "son被删除" << endl;
}
8)multimap和multiset中的中的元素是可以重复的
4、使用map解决top-K问题
从 arr[1, n] 这 n 个数中,找出最大的k个数(这里的k我给的是3,也可以自己定)。
#include <iostream>
#include <vector>
#include <queue>
class Com
{
public:
bool operator()(const std::pair<std::string, size_t>& left, const std::pair<std::string, size_t>& right)
{
return left.second > right.second;
}
};
void TestMap()
{
std::string Fruits[] = { "son", "son", "mom", "mom", "dad", "dad", "sister", "brother", "grandfather", "grandfather", "grandfather", "grandfather", "grandmonther", "grandmonther", "dad", "dad", "dad", "son", "grandson" };
// 使用map统计英文单词的个数
std::map<std::string, size_t> m;
for (auto& e : Fruits)
++m[e];
// 建立大顶堆,找到前三个个数最多的英文单词
std::priority_queue<std::pair<std::string, size_t>, std::vector<std::pair<std::string, size_t>>, Com> p;
int k = 0;
for (auto& e : m)
{
if (k < 3)
{
k++;
p.push(e);
}
else
{
if (e.second > p.top().second)
{
p.pop();
p.push(e);
}
}
}
// 将堆中的元素放在数组中
std::vector<std::string> vec;
while(!p.empty())
{
vec.push_back(p.top().first);
p.pop();
}
// 打印出出现次数最多的单词
for (int i = 0; i < 3; ++i)
{
std::cout << vec[i] << std::endl;
}
}