網站首頁 編程語言 正文
一、關聯式容器
vector、list、deque、forward_list(C++11)等,這些容器統稱為序列式容器,因為其底層為線性序列的數據結構,里面存儲的是元素本身。
而關聯式容器也是用來存儲數據的,與序列式容器不同的是,其里面存儲的是<key, value>結構的鍵值對,在數據檢索時比序列式容器效率更高。 (插入刪除只需挪動指針指向,無需挪動數據,查找時間logN)
關聯式容器有兩種,一種是map、set、multimap、multiset采用樹形結構,他們的底層都是紅黑樹,另一種是哈希結構。
二、set的介紹
1、set是關聯式容器,它表面上只存放value,實際底層中存放的是由<value,value>組成的鍵值對。
2、set調用find將采用中序遍歷,可以用于排序+去重。
3、為了保證元素的唯一性,set中的元素均為const,所以并不能對元素進行修改,但可以進行插入刪除。
1、接口count與容器multiset
count和find的作用一樣,都是用于查找set中是否存在某個元素。
其實count是為了容器multiset設計的,該容器允許插入重復的元素,此時count會返回紅黑樹中被搜索元素的個數。
#include <iostream>
#include <set>
int main ()
{
std::set<int> myset;
// set some initial values:
for (int i=1; i<5; ++i) myset.insert(i*3); // set: 3 6 9 12
for (int i=0; i<10; ++i)
{
std::cout << i;
if (myset.count(i)!=0)
std::cout << " is an element of myset.\n";
else
std::cout << " is not an element of myset.\n";
}
return 0;
}
2、接口lower_bound和upper_bound
lower_bound返回大于等于目標值的迭代器,upper_bound返回大于目標值的迭代器,在set中用于返回目標值的迭代器。(比如找到兩個邊界的迭代器,就可以使用erase對數據進行刪除)
#include <iostream>
#include <map>
int main ()
{
std::map<char,int> mymap;
std::map<char,int>::iterator itlow,itup;
mymap['a']=20;
mymap['b']=40;
mymap['c']=60;
mymap['d']=80;
mymap['e']=100;
itlow=mymap.lower_bound ('b'); // itlow points to b
itup=mymap.upper_bound ('d'); // itup points to e (not d!)
mymap.erase(itlow,itup); // a => 20 e => 100
// print content:
for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
std::cout << it->first << " => " << it->second << '\n';
return 0;
}
三、map的介紹
map是關聯式容器,根據特定的存儲順序,用于存儲由鍵值及其映射值組合的元素。
可以看到Alloc中有一個鍵值對pair,這個pair是一個key/value結構的struct模板類。這個類將一對鍵值耦合在一起,所以,map的存儲方式是通過在搜索二叉樹中存儲鍵值對pair,而搜索二叉樹的k/v模型是在節點中存儲key和value,并不相同。pair的結構:
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)
{}
};
1、接口insert
make_pair是一個函數模板:
template <class T1,class T2>
pair<T1,T2> make_pair (T1 x, T2 y)
{
return ( pair<T1,T2>(x,y) );
}
2、接口insert和operator[]和at
使用map統計每個字符出現個數
寫法2的[]詳解:
Value& operator[] (const Key& k)
{
pair<iterator,bool> ret=insert(make_pair(k,Value() ) );
//在結構體pair中找到first(一個map的迭代器),->解引用找到該迭代器的pair,再找該pair的second(即value)
return ret.first->second;
}
//map的insert
pair<iterator,bool> insert (const value_type& pair);
//插入
dict["迭代器"];//在dict中找不到"迭代器"這個key,將新增一個節點,該節點的key為"迭代器",value為value類型的默認構造
//修改
dict["迭代器"]="iterator";//將key為"迭代器"的節點的value修改為"iterator"
不難看出map的operator[]兼具查找、插入、修改三種功能。(注意如果搜尋值不在map中,map可是會幫你新增一個節點的,map底層的紅黑樹將發生改變)
使用operator[],編譯器會去調用insert(pair<const key,value()>)進行插入,如果沒有找到key所對應的節點,則會新增一個節點并將該節點中pair的value置為value類型的默認構造;如果找到了,則返回該節點pair中value的引用。(可讀可寫)
at的功能和[]一樣,區別在于用at找不到key將不會發生插入新節點,而是拋出異常。
3、容器multimap
multimap多個鍵值對中的key可以重復,所以并沒有operator[]。同樣的,使用find將返回中序遍歷找到的第一個key值所處節點的迭代器。
四、map和set相關OJ
1、前K個高頻單詞
struct Compare
{
bool operator()(const pair<int,string>& a,const pair<int,string>& b)
{
return a.first>b.first || (a.first==b.first&&a.second<b.second);
}
};
class Solution {
public:
vector<string> topKFrequent(vector<string>& words, int k) {
vector<string> ret;
map<string,int> dataMap;
for(const auto& str : words)
{
dataMap[str]++;
}
vector<pair<int,string>> v;
for(auto& kv : dataMap)
{
v.push_back(make_pair(kv.second,kv.first));//dataMap的first是string,second是int
}
sort(v.begin(),v.end(),Compare());
for(int i=0;i<k;++i)
{
ret.push_back(v[i].second);
}
return ret;
}
};
2、兩個數組的交集
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
set<int> s1(nums1.begin(),nums1.end());//nums1排序+去重
set<int> s2(nums2.begin(),nums2.end());//nums2排序+去重
vector<int> ret;
for(auto& e : s1)
{
if(s2.find(e)!=s2.end())
{
ret.push_back(e);
}
}
return ret;
}
};
或者將兩個數組排序+去重完畢后,使用雙指針求解。(可用于找交集,差集)
原文鏈接:https://blog.csdn.net/gfdxx/article/details/129019357
相關推薦
- 2022-04-09 Redis分布式鎖防止緩存擊穿的實現_Redis
- 2022-04-08 python實現有效的括號判斷實例代碼_python
- 2022-10-17 Python速成篇之像selenium一樣操作電腦詳解_python
- 2022-07-27 Python中的sys模塊、random模塊和math模塊_python
- 2022-11-11 Vant 3.* 底部安全區適配 部分頁面不生效
- 2022-02-18 git忽略文件,.gitignore配置
- 2022-05-12 Centos python3 與 python2 共存
- 2022-10-05 Iptables防火墻string模塊擴展匹配規則_安全相關
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支