set / multiset 容器
set 容器
基本概念
简介:所有元素都会在插入时自动被排序
本质:set / multiset 属于关联式容器,底层结构是用 二叉树 实现
set 和 multiset 的区别
- set 不允许容器中有重复的元素,multiset 允许容器可以
- set 插入数据的同时会返回插入结果,表示插入是否成功
- multiset 不会检测数据,因此可以插入重复数据
set 构造和赋值
构造
set<T> st;
// 默认构造函数;set(const set& st);
// 拷贝构造函数
赋值- ` set& operator=(const set &st); // 重载等号操作符
案例
void prt(set<int>& st)
{
for (auto i : st)
cout << i << " ";
cout << endl;
}
void test1()
{
set<int> s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(30);
s1.insert(10);
prt(s1); // 输出 10 20 30
set<int> s2;
s2.insert(10);
s2.insert(20);
s2.insert(30);
prt(s2); // 同样输出 10 20 30
}
set 大小和交换
size();
empty();
swap(st);
set 插入和删除
insert(elem);
clear();
erase(pos);
erase(beg, end);
erase(elem);
// 删除容器中值为 elem 的元素
set 查找和统计
find(key);
// 若 key 存在,返回该键元素的迭代器,若不存在返回set.end()count(key);
// 统计 key 的元素个数,因为set不存在重复的元素,所以始终返回1
pair 对组创建
set 的 insert 操作的实现是 pair<iterator, bool>,multiset 的 insert 操作的实现是 < iterator >
pair<type, type> pr(value1, value2);
pair<type, type> pr = make_pair(value1, value2);
案例
void test1()
{
pair<string, int> p("Tom", 23);
cout << p.first << " " << p.second << endl;
pair<string, int> p2 = make_pair("Bob", 33);
cout << p2.first << " " << p2.second << endl;
}
set 容器排序
利用仿函数,可以改变排序规则
案例1 - 内置数据类型
class Cmp { // 指定仿函数,进行降序排序
public:
bool operator()(int a, int b) const
{
return a > b;
}
};
void sprt(set<int, Cmp>& st)
{
for (auto i : st)
cout << i << " ";
cout << endl;
}
void test2()
{
// 指定排序规则为从大到小
set<int, Cmp> s1;
s1.insert(11);
s1.insert(18);
s1.insert(12);
s1.insert(15);
s1.insert(14);
s1.insert(11);
sprt(s1); // 输出结果 18 15 14 12 11
}
案例2 - 自定义数据类型
对于自定义的数据类型必须要 指定排序规则
class Person { // 自定义数据类型
public:
Person(string name, int age)
{
this->name_ = name;
this->age_ = age;
}
string name_;
int age_;
};
class CpmPers { // 自定义仿函数,进行降序进行排序
public:
bool operator()(const Person& a, const Person& b)
{
// 按照年龄降序
return a.age_ > b.age_;
}
};
void test3()
{
set<Person, CpmPers> s1;
Person p1("Lucy", 22);
Person p2("Mary", 24);
Person p3("Jack", 23);
Person p4("Tomi", 25);
// 默认插入的排序顺序是按照字符串,所以会出现错误
s1.insert(p1);
s1.insert(p2);
s1.insert(p3);
s1.insert(p4);
for (set<Person, CpmPers>::iterator it = s1.begin();
it != s1.end(); ++it) {
cout << "Name: " << it->name_
<< ", Age: " << it->age_ << endl;
}
/* 输出结果:
Name: Tomi, Age: 25
Name: Mary, Age: 24
Name: Jack, Age: 23
Name: Lucy, Age: 22
*/
}
map / multimap 容器
map
概念
- map 中所有元素都是 pair
- pair中第一个元素为 key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
- map / multimap 属于 关联容器 ,底层结构是用二叉树实现。
- 可以根据 key 值快速找到 value 值
map 和 multimap 的区别
- map 中不允许容器中有重复 key 值元素
- multimap 允许容器中有重复 key 值元素
map 构造 和 赋值
map<T1, T2> mp;
// 默认构造函数map<const map& mp);
// 拷贝构造函数map& operator=(const map& mp);
// 重载等号赋值操作符
map 大小 和 交换
size();
// 返回容器中元素的数目empty();
// 判断容器是否为空swap();
// 交换两个集合容器
map 插入 和 删除
insert(elem);
// 在容器中插入元素clear();
erase(pos);
// 删除 pos 位置上所指的元素,返回下一个迭代器erase(beg, end);
erase(key);
// 删除容器中值为 key 的元素
map 查找 和 统计
find(key);
count(key);
// 统计 key 的元素个数,map中没有重复的 key,multimap 的count 可能大于 1
map 容器排序
map 的默认排序规则是 升序
和 set 一样,可以利用仿函数改变排序的规则为 降序
案例
class CmpMap {
public:
bool operator()(int a, int b)
{
return a > b;
}
};
void PrtMap(map<int, int, CmpMap>& m)
{
for (map<int, int, CmpMap>::iterator it = m.begin(); it != m.end(); ++it) {
cout << "key: " << it->first << " Second: " << it->second << endl;
}
cout << endl;
}
void test06()
{
map<int, int, CmpMap> m;
m.insert(pair<int, int>(1, 10));
m.insert(make_pair(2, 20));
m.insert(make_pair(3, 30));
m.insert(make_pair(4, 40));
m.insert(make_pair(5, 50));
PrtMap(m);
}