<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
關聯式容器包括序列式容器和關聯式容器
序列式容器: 底層為線性序列的資料結構,裡面儲存的是元素本身,包含vector、list、deque、forward_list(C++11)等。
關聯式容器: 裡面儲存的是<key, value>結構的鍵值對,在資料檢索時比序列式容器效率更高,包含set、map、unordered_set、unordered_map等。
注意: stack、queue和priority_queue屬於容器介面卡
用來表示具有一一對應關係的一種結構,該結構中一般只包含兩個成員變數key和value,key代表鍵值,value表示與key對應的資訊。
現在要建立一個英漢互譯的字典,那該字典中必然有英文單詞與其對應的中文含義,而且,英文單詞與其中文含義是一一對應的關係,即通過該應該單詞,在詞典中就可以找到與其對應的中文含義。
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) {} };
注意:
set的模板參數列
T: set中存放元素的型別,實際在底層儲存<value, value>的鍵值對。
Compare:set中元素預設按照小於來比較
Alloc:set中元素空間的管理方式,使用STL提供的空間設定器管理
set的構造
函數宣告 | 功能介紹 |
---|---|
set (const Compare& comp = Compare(), const Allocator& =Allocator()); | 構造空的set |
set (InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator() ); | 用[first, last)區間中的元素構造set |
set ( const set<Key,Compare,Allocator>& x); | set的拷貝構造 |
set中常用的成員函數
成員函數 | 功能 |
---|---|
insert | 插入元素 |
erase | 刪除元素 |
find | 查詢元素 |
size | 獲取容器中元素的個數 |
clear | 清空容器 |
empty | 判空 |
swap | 交換兩個容器中的資料 |
count | 獲取某個元素的個數 |
使用範例
int main() { set<int> s; //插入元素(自動去重) s.insert(1); s.insert(4); s.insert(3); s.insert(3); s.insert(2); s.insert(2); s.insert(3); //遍歷容器 for (auto e : s) { cout << e << " "; } cout << endl; //查詢元素 set<int>::iterator pos = s.find(3); //刪除元素 s.erase(pos);// 刪除元素3 s.erase(4); //容器大小 cout << s.size() << endl; //清空容器 s.clear(); //容器判空 cout << s.empty() << endl; //交換兩個容器的資料 set<int> tmp{ 10, 20, 30, 40 }; s.swap(tmp); //容器中值為2的元素個數 cout << s.count(2) << endl; cout << endl; }
執行結果如下
set中迭代器相關函數
成員函數 | 功能 |
---|---|
begin | 返回set中起始位置元素的迭代器 |
end | 返回set中最後一個元素後面的迭代器 |
rbegin | 返回set第一個元素的反向迭代器 |
rend | 返回set最後一個元素下一個位置的反向迭代器 |
使用範例
void test_set() { set<int> s; //插入元素 s.insert(1); s.insert(4); s.insert(3); s.insert(3); s.insert(2); s.insert(2); s.insert(3); //遍歷容器(正向迭代器) set<int>::iterator it = s.begin(); while (it != s.end()) { cout << *it << " "; it++; } cout << endl; //反向迭代器 set<int>::reverse_iterator rit = s.rbegin(); while (rit != s.rend()) { cout << *rit << " "; rit++; } cout << endl; }
執行結果如下
multiset和set的區別是multiset允許資料冗餘,即multiset中允許存在資料相同的元素,而set不能。
void test_set() { set<int> s; s.insert(1); s.insert(3); s.insert(4); s.insert(2); s.insert(2); for (auto e : s) { cout << e << " "; } cout << endl; multiset<int> ms; ms.insert(1); ms.insert(3); ms.insert(4); ms.insert(2); ms.insert(2); for (auto e : ms) { cout << e << " "; } cout << endl; }
執行結果如下
兩個容器中成員函數find意義也有區別:
set中的find是返回值為val的迭代器,而multiset中的find是返回第一個值為val的迭代器。
map的模板引數說明
key: 鍵值對中key的型別
T: 鍵值對中value的型別
Compare: 比較器的型別,map中的元素是按照key來比較的,預設情況下按照小於來比較,一般情況下(內建型別元素)該引數不需要傳遞,如果無法比較時(自定義型別),需要使用者自己顯式傳遞比較規則(一般情況下按照函數指標或者仿函數來傳遞)
Alloc:通過空間設定器來申請底層空間,不需要使用者傳遞,除非使用者不想使用標準庫提供的空間設定器
void test_map() { map<int, double> m1; //構造一個key為int型別,value為double型別的空容器 map<int, double> m2(m1); //拷貝構造 map<int, double> m3(m2.begin(), m2.end()); //利用迭代器拷貝構造 map<int, double, greater<int>> m4; //按int降序排序 }
插入函數原型
pair<iterator,bool> insert (const value_type& val);
這裡的value_type是pair的重新命名
typedef pair<const Key, T> value_type;
方式一: 構造匿名物件插入。
int main() { map<int, string> m; // 構造一個匿名物件插入 m.insert(pair<int, string>(2, "two")); m.insert(pair<int, string>(1, "one")); m.insert(pair<int, string>(3, "three")); for (auto e : m) { cout << e.first << "-" << e.second << endl; } cout << endl; return 0; }
執行結果如下
方式二: 呼叫make_pair函數模板
make_pair函數模板如下
template <class T1, class T2> pair<T1, T2> make_pair(T1 x, T2 y) { return (pair<T1, T2>(x, y)); }
make_pair可以根據傳入引數型別自行推導模板型別
上述程式碼可改為
int main() { map<int, string> m; // 構造一個匿名物件插入 m.insert(make_pair(2, "two")); m.insert(make_pair(1, "one")); m.insert(make_pair(3, "three")); for (auto e : m) { cout << e.first << "-" << e.second << endl; } cout << endl; return 0; }
執行結果相同
insert的返回值也是一個pair物件,pair中第一個成員型別是插入的map的迭代器型別,第二個成員型別是bool型別
bool型別的作用如下
函數原型:
mapped_type& operator[] (const key_type& k);
函數的返回值如下:
(*((this->insert(make_pair(k, mapped_type()))).first)).second
乍一看很是複雜,把括號分清後便明朗許多
原始碼可分解為
mapped_type& operator[] (const key_type& k) { //呼叫insert函數插入鍵值對 pair<iterator, bool> ret = insert(make_pair(k, mapped_type())); //拿出從insert函數獲返回的迭代器 iterator it = ret.first; //返回該迭代器位置元素的值value return it->second; }
應用場景:
void test_map1() { string str[] = { "sort", "sort", "tree", "insert", "sort", "tree", "sort", "test", "sort" }; map<string, int> countMap; for (auto& e : str) { countMap[e]++; } for (auto& e : countMap) { cout << e.first << "-" << e.second << endl; } cout << endl; }
執行結果
map其他常用成員函數
成員函數 | 功能 |
---|---|
void erase ( iterator position ) | 利用迭代器刪除元素 |
size_type erase ( const key_type& x ) | 刪除鍵值為x的元素 |
void erase ( iterator first,iterator last ) | 刪除[first, last)區間中的元素 |
iterator find ( const key_type& x) | 找到返回該元素的位置的迭代器,否則返回end |
size | 獲取容器中元素的個數 |
empty | 判空 |
clear | 清空容器 |
swap | 交換兩個容器中的資料 |
count | 獲取某個元素的個數 |
使用範例
int main() { map<int, string> m; m.insert(make_pair(2, "two")); m.insert(make_pair(1, "one")); m.insert(make_pair(3, "three")); m.insert(make_pair(4, "four")); //根據key值進行刪除 m.erase(3); //根據迭代器進行刪除 map<int, string>::iterator pos = m.find(4); if (pos != m.end()) { m.erase(pos); } // 獲取元素為2的迭代器 pos = m.find(2); if (pos != m.end()) { cout << pos->first<<"-"<<pos->second << endl; } //獲取容器中元素的個數 cout << m.size() << endl; //容器中key值為2的元素個數 cout << m.count(2) << endl; //清空容器 m.clear(); //容器判空 cout << m.empty() << endl; //交換兩個容器中的資料 map<int, string> tmp; m.swap(tmp); return 0; }
map的迭代器相關函數
成員函數 | 功能 |
---|---|
begin | 返回map中起始位置元素的迭代器 |
end | 返回map中最後一個元素後面的迭代器 |
rbegin | 返回map第一個元素的反向迭代器 |
rend | 返回map最後一個元素下一個位置的反向迭代器 |
操作演示
int main() { map<int, string> m; m.insert(make_pair(2, "two")); m.insert(make_pair(1, "one")); m.insert(make_pair(3, "three")); // 正向迭代器遍歷 map<int, string>::iterator it = m.begin(); while (it != m.end()) { cout << it->first << "-" << it->second << endl; it++; } cout << endl; // 反向迭代器遍歷 map<int, string>::reverse_iterator it2 = m.rbegin(); while (it2 != m.rend()) { cout << it2->first << "-" << it2->second << endl; it2++; } cout << endl; return 0; }
multimap容器和map容器的區別與multiset容器和set容器的區別一樣,multimap允許鍵值冗餘,即multimap容器當中儲存的元素是可以重複的。
int main() { multimap<int, string> mt; //插入元素(允許重複) mt.insert(make_pair(2, "two")); mt.insert(make_pair(2, "two")); mt.insert(make_pair(1, "one")); mt.insert(make_pair(3, "three")); for (auto e : mt) { cout << e.first << "-" << e.second << endl; } cout << endl; return 0; }
注意: 由於multimap容器允許鍵值冗餘,呼叫[ ]運運算元過載函數時,應該返回鍵值為key的哪一個元素的value的參照存在歧義,因此在multimap容器不支援[ ]運運算元過載函數。
到此這篇關於C++中map和set的簡介及使用詳解的文章就介紹到這了,更多相關C++ map和set內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45