# STL - 2 --- # 集合 set ---- * 大小不固定 * 同個東西只有一個 * 沒有隨機存取,但有順序 ---- ```cpp= // 創建 set<int> set1; // 創造空集合 set<int> set2{2, 1, 3, 4}; // 給集合初始元素 // 集增加、修改、刪除元素 set1.insert(0); // 加入元素 int c = set2.erase(3); // 刪除元素,回傳刪了幾個 int cnt = set2.count(4); // 回傳有幾個指定元素 // 集合整體 int len = set2.size(); // 集合大小 bool emp = set1.empty(); // 是否沒有元素 set1.clear(); // 清空集合 ``` ---- ```cpp=11 // 迭代器 for (auto it = set2.begin(), it != set2.end(), it++){ cout << *it << ' '; // 迭代遍歷 } // 反向遍歷用 .rbegin(), .rend() // 1 2 4 for (auto &i : set2){} // 另一種遍歷方法 auto it = set2.find(4); // 找元素的迭代器,找不到會回傳.end() set2.erase(it); // 刪除迭代器指向的位置 ``` ---- ## 練習題 [ZJ d478.](https://zerojudge.tw/ShowProblem?problemid=d478) ---- ## unordered_set 跟set幾乎一樣,但是不會排序。 後加入的就會在迭代器較後面。 ---- ## multiset 也是set,但允許重複元素 如果 .erase() 元素名,會刪除全部相同的元素 .erase() 和 .count() 都會回傳元素數量 ---- ## unordered_multiset 具有unordered_set和multiset兩種特性的set 不會排序,而且元素可以重複 --- # 配對 pair ---- - pair可以將兩個資料綁在一起 - pair的兩個值可以是不同類型 - 如果是兩項都可以比,則同類的pair也可以比 - 會先比前項,再比後項 ---- ```cpp= // 創造 pair<int, char> p1(100, 'a'), p2(10, 'c'); // 初始化pair auto p3 = make_pair<int, char>(5, 'z'); // 用make_pair創造 // 改變、讀取 p1.first = 10; // .first 和 .second 可以存取個別的 cout << p1.first << ' ' << p1.second << '\n'; // 比較 cout << (p1>p3) << '\n'; // true,比first,10>5,所以p1>p3 cout << (p1>p2) << '\n'; // false // 先比first,10==10,比second,'a'<'c',所以p1<p2 ``` ---- - 常搭配陣列,用來排序的同時保持關係 [ZJ h075.](https://zerojudge.tw/ShowProblem?problemid=h075) [ZJ d536.](https://zerojudge.tw/ShowProblem?problemid=d536) --- # 字典 map ---- - map類似vector,但會一次儲存兩個值 - 第一個值是索引,不會重複 - 第二個值是元素,要用索引來存取 - 會依索引排序,預設由小到大 ---- ```cpp= // 創造 map<string, int> map1; map<string, int> map2 = {{"wow",1}, {"hi",2}}; // 存取、修改、增加、刪除 cout<<map2["hi"]<<'\n'; // 回傳索引"hi"對應元素 map2["wow"] = 0; // 把"wow"對應的元素改成0 map1["who"] = 100; // 新增索引"who",對應元素100 map2.insert(pair<string,int>("here", 5)); // 用pair來新增 int c = map2.erase("wow"); // 刪除索引"wow",回傳刪了幾個 int cnt = map2.count("hi"); // 尋找索引是"hi"的有幾個 auto it = map2.find("wow"); // 找指向索引是"wow"的迭代器 //因為找不到,所以回傳map2.end() ``` ---- ```cpp=13 // 整體 int len = map2.size(); // 回傳map2有幾項 bool emp = map1.empty(); // 回傳map1是否是空的 map1.clear(); // 清空map1 // 遍歷 for(auto i : map2){ // i會是pair cout<<i.first<<' '<<i.second<<'\n'; } for (auto it = map2.begin(); it != map2.end(); it++) // 迭代器 ``` ---- ## unordered_map 不會依索引排序的map 依時間先後排序 會比map稍微快一點。 ---- ## multimap 同個索引可以對到多個元素,無法直接以索引存取 同索引依先後順序排序 許多和map的差異就像multiset和set的差異 像是pair的vector ---- ## unordered_multimap 同時unordered又multi的map 不排序,不能直接存取,可以重複索引 --- # 元組 tuple ---- - tuple可以建立容納多種類型的元素 - 如果內容物允許比較,tuple就可以比較 ---- ```cpp= // 創建 tuple<int, int, double> tuple1(10, 2, 0.5); auto tuple2 = make_tuple<int, int, double>(0, 8, 1.0); // 存取、變更 cout << get<1>(tuple1) << '\n'; // 得到tuple1的第二項 get<0>(tuple2) = 10; // 將tuple2的第一項改成10 // 拆開 int i1, i2; double d1; tie(i1, i2, d1) = tuple1; // i1=10, i2=2, d1=0.5 // 比較 cout << (tuple1>tuple2); // 先比10==10,接著2<8,所以是false ``` ---- ## 練習題 [ZJ a362.](https://zerojudge.tw/ShowProblem?problemid=a362)
{"title":"STL - 2","contributors":"[{\"id\":\"00ad9127-6491-4b3d-829b-7847a217f8e5\",\"add\":3952,\"del\":829}]","description":"標準程式庫"}
    136 views