【C++】STL(2) -关联容器

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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值