文章目录
1. map
1.1 有序字典
1.1.1 map:有序不可重复key的字典
#include <map>
map< string, float > mp1; // 空字典
map< string, float> mp2 = { // 定义时初始化
{"pen", 20},
{"pensil", 1.5},
{"sharpener", 1.5}
};
// 插入:只要item不存在就是插入
mp2.insert( {"eraser", 3.2 } );
mp2.insert( make_pair( "ink", 5 ) );
mp2["paper"] = 1.5;
// 修改:只要item存在就是修改
mp2.insert({"pensil", 1});
mp2.insert(make_pair("pensil", 2));
mp2["pensil"] = 3;
mp2.begin()->second = 1.1; // 使用迭代器修改
// 删除: 使用key删除
mp2.erase("ink");
// 删除:使用删除项的迭代器删除
auto it = mp2.find("ink");
if(it != mp2.end()){
mp2.erase(it);
}
// 遍历1
for( auto mapItem : map1 ){
cout << mapItem.first << '\t' << mapItem.second << endl;
}
// 遍历2
for(auto it=map1.begin(); it != map1.end(); it++){
cout << *it << " ";
}
// 查找
auto it = mp2.find("ink");
if( it != mp2.end()){
cout << "ink found!" << endl;
}
// 获取长度
cout << mp2.size();
// 是否为空
if(mp2.empty()){
cout << "empty!" << endl;
}
// 指定排序方向
map<string, float, less<string>> mp3; // 升序,默认
map<string, float, greater<string>> mp4; // 降序
// 自定义类型时,指定排序方向
struct Greater{
template<typename T> bool operator()(const T& a, const T& b) const{
return a > b;
}
}
map<string, int, Greater>mp;
1.1.2 multimap:有序可重复key的字典
#include <map>
multimap<string, float> mmp1; // 空字典
multimap<string, float> mmp2 = { // 定义时初始化
{"pen", 20},
{"pensil", 15},
{"eraser", 3.5}
};
// 插入
mmp2.insert({"ink", 4});
mmp2.insert(make_pair("pen", 18)); // 插入相同key的item
mmp2["ink"] = 5;
// 修改:不能使用[]和insert()方法,只能使用迭代器
auto it = mmp2.find("ink"); // 第一个key=ink的item
it->second = 6;
// 修改:修改所有ink项的值
auto ret = mmp2.equal_range("ink");
for(auto it = ret.first; it != ret.second; it++){
it->second = 3;
}
// 删除元素:删除所有key=pen的item
mmp2.erase("pen");
// 删除元素:删除第一个key=pen的item
auto it = mmp2.find("pen");
mmp2.erase(it);
// 遍历1
for(auto elem: mmp2){
cout << elem.first << "\t" << elem.second << endl;
}
// 遍历2
for(auto it=mmp2.begin(); it!=mmp2.end();it++){
cout << it->first << "\t" << it->second << endl;
}
// 查找:找到第一个找到的item
auto it = mmp2.find("pen");
if( it != mmp2.end()){
cout << it->first<< "'s price: " << it->second << endl;
}
// 查找:找到所有相同key的item
auto range = mmp2.equal_range("pen"); // 返回pair对象,第一个元素为首个item迭代器,第二个元素为最后一个item的下一个位置上的迭代器
for (auto it = range.first; it != range.second; ++it) {
cout << "pen's price: " << it->second << endl;
}
// 获取长度
cout << mmp2.size();
// 获取指定item的个数
cout << mmp2.count("pen");
// 是否为空
if(mp2.empty()){
cout << "empty!" << endl;
}
// 指定排序方向
multimap<string, float, less<string>> mmp3; // 升序,默认
multimap<string, float, greater<string>> mmp4; // 降序
// 自定义类型时,指定排序方向
struct Greater{
template<typename T> bool operator()(const T& a, const T& b) const{
return a > b;
}
}
multimap<string, int, Greater> mmp;
1.2 无序字典
1.2.1 unordered_map:无序不可重复key的字典
- 基本用法和map一致,参考2.1.1。
- 底层数据结构:哈希表。
1.2.2 unordered_multimap:无序可重复key的字典
- 基本用法和map一致,参考2.1.2。
- 底层数据结构:哈希表。
2. set
2.1 有序集合
2.1.1 set:有序不重复元素的集合
#include <set>
set<int> s0 = {2, 1, 3}; // s0={1,2,3}
set<int, less<int>> s1 = {1, 2, 3}; // s={1,2,3}
// 插入操作:如果元素已存在,插入操作被忽略
s1.insert(1); // 返回pair对象,其第一个值是指向插入项的const_iterator,第二个值是指示插入操作是否成功的bool值。
// 删除
s1.erase(2);
s1.erase(s.begin());
// 查找
auto it = s1.find(3);
if(it!= s1.end()){
cout << "found!" << endl;
}
// 遍历1
for(auto elem : s1){
cout << elem << " ";
}
// 遍历2
for(auto it = s1.begin(); it != s1.end(); it++){
cout << *it << endl;
}
// 是否为空
if(s1.empty()){
cout << "set is empty!" << endl;
}
// 获取长度
cout << s1.size();
// 指定排序方向
set<int, less<int>> s2 = {1, 2, 3}; // 升序,默认方向
set<int, greater<int>> s3={2,1,3}; // 降序
// 自定义比较函数,创建降序集合
struct Greater{
template<typename T> bool operator()(const T &a, const T&b){
return a >= b;
}
};
set<int, Greater> s1={1,2,3};
2.1.2 multiset:有序可重复元素的集合
#include <set>
multiset<int> ms = {2,3,2,1,4};
// 插入
ms.insert(3); // 插入已存在的元素
ms.insert(5); // 插入不存在的元素
// 查找第一个匹配的
ms.find(2);
// 查找所有匹配的
auto ret = ms.equal_range(2);
for(auto it = ret.first; it != ret.second; it++){
cout << *it << " ";
}
cout << endl;
// 删除所有值为2的元素方法一
ms.erase(2);
// 删除所有值为2的元素方法二
auto ret = ms.euqal_range(2);
for(auto it = ret.first; it != ret.second; it++){
ms.erase(it);
}
// 删除第一个值为2的元素
auto it = ms.find(2);
ms.erase(it;
// 获取长度
cout << ms.size();
// 是否为空
if(ms.empty()){
cout << "empty!" <<endl;
}
// 统计元素的个数
cout << ms.count(3) << endl;
2.2 无序集合
2.2.1 unordered_set
- 基本用法和set一致,参考2.1.1
- 底层数据结构:哈希表。
2.2.2 unordered_multiset
- 基本用法和set一致,参考2.1.2
- 底层数据结构:哈希表。
3 总结
-
底层数据结构:有序关联容器(set,multiset,map,multimap):红黑树;无序关联容器(unordered_set,unordered_multiset,unordered_map,unordered_multimap):哈希表。
- 红黑树特点:叶子结点都是空节点,代表查询失败的一种情况;左根右,根叶红,黑路同,不红红;高度上界:h <= 2log(n+1)。
- 哈希表特点:查询O(1);冲突解决:链表法,开放地址法;buckectAddr=hash(key)。
-
可重复的关联容器的一些特性
- 只能使用insert()方法插入。无法使用下标插入,因为无法通过key唯一标识item。
- 重复项连续地排列,可使用equal_range()方法找到连续的重复项,返回第一项迭代器和最后一项的下一个位置上的迭代器。
- 可以通过count()方法统计重复项的个数。
-
有序关联容器的排序方向:元素为基本类型时,指定升序使用
less<int>
,指定降序使用greater<type>
。自定义类型则需要重载运算符"()"。 -
不可重复的字典:可以使用[],insert()方法和迭代器来修改或者插入item(若item不存在,则操作为插入操作,若item存在,则操作为修改操作)。
-
可重复的字典:只能使用迭代器修改item。只能使用insert()方法插入item。
-
支持随机访问的容器(vector,deque等)可以使用 it+i 形式获取迭代器;不支持随机访问的容器(set,map,list等),只能使用 it++ 形式获取迭代器。
-
erase()删除失败(如删除不存在的key)返回0,删除成功返回1。