当前位置:首页 » 《我的小黑屋》 » 正文

C++ STL中 set 和 map 的区别

15 人参与  2024年11月07日 12:04  分类 : 《我的小黑屋》  评论

点击全文阅读


目录

1.引言

2.set

3.map

4.共同点

5.不同点

6.高级用法与注意事项

7.总结


1.引言

        在C++的标准模板库(STL)中,setmap是两种常用的容器,它们提供了不同的功能和使用场景。尽管它们底层都基于红黑树实现,有许多相似之处,但在具体用途和接口上却有明显的区别。本文将详细探讨setmap的差异,帮助大家在实际编程中更好地选择和使用它们。

2.set

set是一种关联容器,主要用于存储唯一的、已排序的元素。在set中,每个元素都是唯一的,且set会自动根据元素的值进行排序(默认按升序)。试图插入重复元素将被忽略,这是set设计的初衷。确保插入前元素的唯一性,或利用此特性进行去重或排序。set内部实现通常采用红黑树,因此其插入、删除和查找操作的时间复杂度为O(log n)。

#include <set>#include <iostream>int main() {    std::set<int> mySet = {3, 1, 4, 1, 5, 9};  // 自动排序并去重    for (int num : mySet) {        std::cout << num << " ";    }    mySet.insert(10); // 成功插入    mySet.insert(10); // 重复,不会插入    return 0;}

3.map

map也是一种关联容器,但它存储的是键值对(key-value pairs)。在map中,每个键都是唯一的,且map会根据键的值自动排序(默认按升序)。值可以重复。键用于排序和查找,值则存储实际数据。尝试插入已存在的键会导致插入失败,而不是覆盖原有值。若需覆盖,请先检查键是否存在,再决定插入或更新。set类似,map的内部实现也基于红黑树,因此其插入、删除和查找操作的时间复杂度同样为O(log n)。

#include <iostream>#include <map>using namespace std; #include <string> void TestMap(){map<string, string> m;// 向map中插入元素的方式:// 将键值对<"peach","桃子">插入map中,用pair直接来构造键值对m.insert(pair<string, string>("peach", "桃子"));// 将键值对<"peach","桃子">插入map中,用make_pair函数来构造键值对m.insert(make_pair("banan", "香蕉")); // 借用operator[]向map中插入元素/*operator[]的原理是:用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器operator[]函数最后将insert返回值键值对中的value返回 */ // 将<"apple", "">插入map中,插入成功,返回value的引用,将“苹果”赋值给该引用结果,m["apple"] = "苹果";// key不存在时抛异常//m.at("waterme") = "水蜜桃";cout << m.size() << endl;// 用迭代器去遍历map中的元素,可以得到一个按照key排序的序列for (auto& e : m)cout << e.first << "--->" << e.second << endl; // 遍历键值对cout << endl;// map中的键值对key一定是唯一的,如果key存在将插入失败auto ret = m.insert(make_pair("peach", "桃色"));if (ret.second)cout << "<peach, 桃色>不在map中, 已经插入" << endl;elsecout << "键值为peach的元素已经存在:" << ret.first->first << "--->" <<ret.first->second << " 插入失败" << endl;// 删除key为"apple"的元素m.erase("apple");if (1 == m.count("apple"))cout << "apple还在" << endl;elsecout << "apple被吃了" << endl;} int main(){TestMap();return 0;}

4.共同点

有序性set 和 map 都是有序的容器,它们的元素会根据一定的排序准则(通常是 < 运算符,但也可以是自定义的比较函数或函数对象)自动排序。唯一性set 和 map 中的元素都是唯一的,不允许有重复的元素。自动平衡:它们的底层实现通常基于红黑树(Red-Black Tree),因此插入、删除和查找操作的时间复杂度都是 O(log n)。

5.不同点

存储的元素类型set 存储的是单个元素,每个元素都是唯一的。map 存储的是键值对(key-value pairs),其中键(key)是唯一的,但值(value)可以重复。元素访问方式set 中的元素只能通过迭代器访问,或者通过 find 方法查找。map 中的元素可以通过键(key)直接访问,例如 map[key],或者通过 find 方法查找。迭代器类型set 的迭代器指向的是单个元素。map 的迭代器指向的是键值对(pair<const Key, T>)。适用场景set 适用于需要存储唯一元素并且需要排序的场景,比如去重和排序后的集合。map 适用于需要存储键值对并且需要根据键进行快速查找、插入和删除的场景,比如字典或缓存。

额外功能

     1.set:提供如lower_boundupper_bound等成员函数,方便进行范围查找;

                            支持一些集合运算,如并集、交集、差集等(通过STL算法库实现)。    

     2.mapmap的键可以是任意类型,只要支持<操作符(或提供自定义比较函数)。

                            map的值可以是任意类型,甚至是另一个mapset

     6.性能对比

        在大多数情况下,setmap的性能是相近的,因为它们的底层实现都是红黑树。然而,由于map需要额外存储键和值,因此在内存占用上可能会比set更高一些。

6.高级用法与注意事项

1. 自定义排序

我们可以通过提供自定义的比较函数或函数对象来改变setmap的默认排序行为。

set:

#include <set>#include <iostream>#include <functional>struct MyStruct {    int id;    std::string name;};// 自定义比较函数bool compareMyStruct(const MyStruct& a, const MyStruct& b) {    return a.id < b.id;}int main() {    std::set<MyStruct, std::function<bool(const MyStruct&, const MyStruct&)>> mySet(compareMyStruct);    mySet.insert({1, "Alice"});    mySet.insert({2, "Bob"});    mySet.insert({3, "Charlie"});    for (const auto& item : mySet) {        std::cout << item.id << ": " << item.name << std::endl;    }    return 0;}

map:

#include <map>#include <iostream>#include <string>#include <functional>// 自定义比较函数struct CustomCompare {    bool operator()(const std::string& a, const std::string& b) const {        return a > b;  // 降序排序    }};int main() {    std::map<std::string, int, CustomCompare> myMap;    myMap["apple"] = 1;    myMap["banana"] = 2;    myMap["cherry"] = 3;    for (const auto& pair : myMap) {        std::cout << pair.first << ": " << pair.second << std::endl;    }    return 0;}

2.多线程安全

setmap都不是线程安全的,如果在多线程环境中使用,需要手动进行同步。

3.迭代器失效

setmap中,插入不会使迭代器失效,但删除操作会使指向删除元素的迭代器失效。因此,在进行删除操作时,需要特别注意迭代器的有效性。

7.总结

setmap是C++ STL中两种重要的关联容器,它们各自有不同的特点和适用场景。set主要用于存储唯一且排序的元素,而map则用于存储键值对,并根据键进行排序。尽管它们在底层实现上有许多相似之处,但在接口和使用上却有明显的区别。通过理解这些区别,我们可以更好地选择和使用它们,以满足不同的编程需求。


点击全文阅读


本文链接:http://zhangshiyu.com/post/183615.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 祖母寿宴,侯府冒牌嫡女被打脸了(沈屿安秦秀婉)阅读 -
  • 《雕花锦年,昭都旧梦》(裴辞鹤昭都)完结版小说全文免费阅读_最新热门小说《雕花锦年,昭都旧梦》(裴辞鹤昭都) -
  • 郊区41号(许洛竹王云云)完整版免费阅读_最新全本小说郊区41号(许洛竹王云云) -
  • 负我情深几许(白诗茵陆司宴)完结版小说阅读_最热门小说排行榜负我情深几许白诗茵陆司宴 -
  • 九胞胎孕妇赖上我萱萱蓉蓉免费阅读全文_免费小说在线看九胞胎孕妇赖上我萱萱蓉蓉 -
  • 为保白月光,侯爷拿我抵了债(谢景安花田)小说完结版_完结版小说全文免费阅读为保白月光,侯爷拿我抵了债谢景安花田 -
  • 陆望程映川上官硕《我的阿爹是带攻略系统的替身》最新章节阅读_(我的阿爹是带攻略系统的替身)全章节免费在线阅读陆望程映川上官硕
  • 郑雅琴魏旭明免费阅读_郑雅琴魏旭明小说全文阅读笔趣阁
  • 头条热门小说《乔书意贺宴临(乔书意贺宴临)》乔书意贺宴临(全集完整小说大结局)全文阅读笔趣阁
  • 完结好看小说跨年夜,老婆初恋送儿子故意出车祸_沈月柔林瀚枫完结的小说免费阅读推荐
  • 热推《郑雅琴魏旭明》郑雅琴魏旭明~小说全文阅读~完本【已完结】笔趣阁
  • 《你的遗憾与我无关》宋怀川冯洛洛无弹窗小说免费阅读_免费小说大全《你的遗憾与我无关》宋怀川冯洛洛 -

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1