C++ setmap

💓博主CSDN主页:麻辣韭菜💓

⏩专栏分类:C++知识分享⏪

🚚代码仓库:C++高阶🚚

🌹关注我🫵带你学习更多C++知识
  🔝🔝



目录

前言 

 一.树形结构的关联式容器

(一)set

1.1 set介绍

 1.2 set模板参数

1.3 set成员函数

1.4 set使用 

 (二)multiset

1.1multiset介绍 

2.2 multiset模板参数 

 2.3 multiset常用成员函数 

2.4multiset使用 

 (三)map   

3.1 man介绍 

3.2 pair 

3.3 map常用函数 

 3.4 map使用

 (四) multimap

(五)set和map OJ题 

 1.692. 前K个高频单词 - 力扣(LeetCode)

 2.349. 两个数组的交集 - 力扣(LeetCode)


前言 

C++二叉搜索树 最后简单的讲解了搜索二叉树的应用场景,而本篇的set对应的就是K模型,

map对应KV模型。

 一.树形结构的关联式容器

(一)set

1.1 set介绍

set是C++标准模板库(STL)中的一个关联容器,它包含唯一元素的集合。以下是关于set的一些基本介绍:

  1. 唯一性:set中的元素都是唯一的,重复的元素在插入时会被自动忽略。

  2. 自动排序:set中的元素默认按照升序排序。如果需要自定义排序规则,可以通过提供比较函数或重载<运算符来实现。

  3. 迭代器:set支持前向迭代器,可以用来遍历容器中的元素。

  4. 常用操作:

  • insert():向set中插入一个元素。

  • find():查找一个元素是否存在于set中。

  • erase():删除一个元素。

  • size():返回set中元素的个数。

  • empty():检查set是否为空。

  • begin() 和 end():返回指向set中第一个元素和尾后位置的迭代器。

  1. 复杂度:set的插入、删除和查找操作的平均时间复杂度都是O(log n),其中n是set中元素的个数。

  2. 底层实现:set通常使用红黑树(一种自平衡的二叉搜索树)来实现,以确保元素的排序和快速查找。

 1.2 set模板参数

  • T: set中存放元素的类型,实际在底层存储<value, value>的键值对。
  • Compareset中元素默认按照小于来比较
  • Allocset中元素空间的管理方式,使用STL提供的空间配置器管理

1.3 set成员函数

  1. 构造函数:用于创建set对象。

  2. 析构函数:用于释放set对象占用的资源。

  3. begin():返回指向容器中第一个元素的迭代器。

  4. end():返回指向容器“尾部之后”的迭代器。

  5. rbegin():返回指向容器中最后一个元素的反向迭代器。

  6. rend():返回指向容器“起始之前”的反向迭代器。

  7. empty():检查容器是否为空。

  8. size():返回容器中元素的数量。

  9. max_size():返回容器可能包含的最大元素数量。

  10. clear():删除容器中的所有元素。

  11. insert(const value_type& val):在容器中插入一个元素。

  12. erase(const_iterator pos):删除迭代器pos指向的元素。

  13. erase(const key_type& key):删除键为key的元素。

  14. erase(const_iterator first, const_iterator last):删除范围[first, last)内的元素。

  15. find(const key_type& key) const:查找键为key的元素,若找到则返回指向该元素的迭代器,否则返回end()

  16. count(const key_type& key) const:返回键为key的元素在容器中出现的次数(对于set,这个值总是0或1,因为set中的元素是唯一的)。

  17. lower_bound(const key_type& key) 和 upper_bound(const key_type& key):返回指向不小于(大于)键key的第一个元素的迭代器。

  18. equal_range(const key_type& key):返回一个包含两个迭代器的pair,表示键为key的元素在容器中的范围。对于set,如果元素存在,这个范围只包含一个元素;如果不存在,这个范围是[end(), end())

1.4 set使用 

#include <iostream>
#include <string>
#include <map>
#include <set>using namespace std;void set_test()
{set<string> s;s.insert("张三");s.insert("李四");s.insert("王二麻子");s.insert("赵六");s.insert("孙七");set<string>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;auto it1 = s.begin();while (it1 != s.end()){cout << *it1 << " ";++it1;}cout << endl;
}
void set_test2()
{//排序+去重set<int> s1;s1.insert(3);s1.insert(1);s1.insert(4);s1.insert(2);s1.insert(1);s1.insert(2);auto it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";++it1;}cout << endl;
}int main()
{set_test();return 0;
}

 set 和vector list stack queue 这些容器使用方法到差不差 这里就不细讲了!!!

 (二)multiset

 

set前面加multi顾名思义那就是可以插入相同的值。 

1.1multiset介绍 

1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。

2. multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成

的键值对,因此value本身就是keykey就是value,类型为T). multiset元素的值不能在容器

中进行修改(因为元素总是const),但可以从容器中插入或删除。

3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。

4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭

代器遍历时会得到一个有序序列。

5. multiset底层结构为二叉搜索树(红黑树)

5. multiset中的元素不能修改

6. multiset中找某个元素,时间复杂度为$O(log_2 N)$

7. multiset的作用:可以对元素进行排序

2.2 multiset模板参数 

 2.3 multiset常用成员函数 

 

multiset是C++ STL(标准模板库)中的一个容器,它允许存储重复的元素,并且元素在multiset中自动排序。下面是multiset的一些基本函数:

  1. 构造函数

    • multiset<T>(): 创建一个空的multiset
    • multiset<T>(const multiset& other): 创建一个multiset作为另一个multiset的副本。
  2. 插入元素

    • pair<iterator, bool> insert(const value_type& val): 插入一个元素。如果插入成功,返回指向新插入元素的迭代器;如果元素已存在,则不插入并返回指向已存在元素的迭代器。
    • void insert(const_iterator position, const value_type& val): 在指定位置前插入一个元素。注意,由于multiset是有序的,这个“位置”只是一个提示,实际插入位置可能根据元素的值进行调整。
    • void insert(const_iterator first, const_iterator last): 插入一个范围内的元素。
    • void insert(initializer_list<value_type> il): 使用初始化列表插入元素。
  3. 删除元素

    • size_type erase(const key_type& key): 删除所有等于指定键的元素,并返回删除的元素数量。
    • iterator erase(const_iterator position): 删除位于指定位置的元素,并返回指向下一个元素的迭代器。
    • iterator erase(const_iterator first, const_iterator last): 删除一个范围内的元素,并返回指向下一个元素的迭代器。
  4. 查找元素

    • iterator find(const key_type& key): 查找第一个等于指定键的元素,如果找到则返回指向该元素的迭代器,否则返回end()
    • size_type count(const key_type& key) const: 返回等于指定键的元素数量。
    • iterator lower_bound(const key_type& key): 返回指向第一个不小于指定键的元素的迭代器。
    • iterator upper_bound(const key_type& key): 返回指向第一个大于指定键的元素的迭代器。
    • pair<iterator, iterator> equal_range(const key_type& key): 返回一个范围,包含所有等于指定键的元素。
  5. 修改容器大小

    • void clear(): 删除multiset中的所有元素。
  6. 获取容器信息

    • bool empty() const: 如果multiset为空,则返回true
    • size_type size() const: 返回multiset中的元素数量。
    • iterator begin(): 返回指向第一个元素的迭代器。
    • const_iterator begin() const: 返回指向第一个元素的常量迭代器。
    • iterator end(): 返回指向multiset末尾之后位置的迭代器。
    • const_iterator end() const: 返回指向multiset末尾之后位置的常量迭代器。
    • reverse_iterator rbegin(): 返回指向最后一个元素的反向迭代器。
    • const_reverse_iterator rbegin() const: 返回指向最后一个元素的常量反向迭代器。
    • reverse_iterator rend(): 返回指向multiset开头之前位置的反向迭代器。
    • const_reverse_iterator rend() const: 返回指向multiset开头之前位置的常量反向迭代器。 这些函数可以让你有效地在multiset上进行各种操作。记住,由于multiset是有序的,因此插入和查找操作的复杂度通常是对数级别的。

2.4multiset使用 

#include <iostream>
#include <set>
#include <string>using namespace std;int main()
{// 1. 定义multiset,存储string类型multiset<string> ms;// 2. 插入元素ms.insert("apple");ms.insert("banana");ms.insert("apple");ms.insert("cherry");// 3. 访问元素for (auto it = ms.begin(); it != ms.end(); ++it) {cout << *it << " ";}cout << endl;// 4. 删除元素// 删除第一个出现的"apple"auto it = ms.find("apple");if (it != ms.end()) {ms.erase(it);}// 再次访问元素cout << "After deleting an 'apple': ";for (auto it = ms.begin(); it != ms.end(); ++it) {cout << *it << " ";}cout << endl;return 0;
}

 (三)map   

3.1 man介绍 

map是C++标准库中的一个关联容器,它存储的元素都是键值对(key-value pair),并且允许基于键快速访问各个元素。map中的元素总是按键值进行排序存储的。 以下是关于map的基本介绍:

1.存储结构:

  • map内部通常实现为一个平衡搜索树(比如红黑树),因此其元素的插入、删除和查找的时间复杂度都是对数级别的。

2.元素类型:

  • map中的元素是键值对(pair),其中键(key)是唯一的,用于标识元素,而值(value)是与该键相关联的数据。

3.键的唯一性:

  • map中,每个键只出现一次。如果试图插入具有相同键的新元素,该操作会替换原有的元素值。

4.排序:

  • map中的元素按键的升序自动排序。默认情况下,键的比较使用std::less<Key>,但也可以指定自定义的比较函数或对象。

5.基本操作:

  • 插入元素:使用insert成员函数或operator[](后者在键不存在时会创建一个新元素)。

  • 访问元素:使用operator[]at成员函数通过键来访问值。如果键不存在,operator[]会插入一个新元素并返回其引用,而at会抛出一个异常。

  • 删除元素:使用erase成员函数。

  • 查找元素:使用find成员函数来查找具有指定键的元素。

  • 遍历元素:可以使用迭代器来遍历map中的所有元素。

3.2 pair 

 

3.3 map常用函数 

插入元素

  • insert(const value_type& val): 插入一个元素(键值对)。

  • insert(const_iterator position, const value_type& val): 在指定位置前插入一个元素。

  • insert(InputIterator first, InputIterator last): 插入一个元素范围。

查找元素

  • find(const key_type& k): 查找键为k的元素,如果找到则返回指向该元素的迭代器,否则返回end()

  • count(const key_type& k): 查找键为k的元素的数量,因为map中的键是唯一的,所以结果要么是0(没找到)要么是1(找到了)。

删除元素

  • erase(const key_type& k): 删除键为k的元素。

  • erase(const_iterator position): 删除指定位置的元素。

  • erase(const_iterator first, const_iterator last): 删除一个元素范围。

获取元素数量

  • size(): 返回map中元素的数量。

判断map是否为空

  • empty(): 如果map为空则返回true,否则返回false。

访问元素

  • operator[] (const key_type& k): 通过键访问元素,如果键不存在则插入一个具有该键的新元素,并初始化为默认值。

  • at(const key_type& k): 通过键访问元素,如果键不存在则抛出std::out_of_range异常。

获取最大和最小元素

  • begin()end(): 分别返回指向map中第一个和最后一个元素的迭代器。

  • rbegin()rend(): 分别返回指向map中最后一个和第一个元素的反向迭代器(即从后往前遍历)。

修改键值

  • map中的键在插入后不能被修改,但是可以通过删除旧元素并插入新元素来“修改”键。值则可以通过迭代器或引用直接修改

 

 3.4 map使用

void map_test1()
{map<string, int> dict;dict.insert(make_pair("one", 1));dict.insert(make_pair("two", 2));dict.insert(make_pair("three", 3));dict.insert(make_pair("four", 4));//插入也可以用方括号dict["five"] = 5;dict["six"] = 6;dict["six"] = 6; //插入失败map<string, int>::iterator it = dict.begin();while (it != dict.end()){//cout << (*dict).first << ":" << (*dict).second << endl;cout << it->first << ":" << it->second << " ";++it;}cout << endl;}
void map_test2()
{string arr[] = { "西瓜", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉", "梨" };map<string, int> countMap;//传统写法插入for (auto& e : arr){auto ret = countMap.find(e);if (ret == countMap.end()){countMap.insert(make_pair(e, 1));}else{ret->second++;}}for (auto &kv : countMap){cout << kv.first << ": " << kv.second << endl;}// 【】写法/*for (auto& e : arr){countMap[e]++;}for (auto& kv : countMap){cout << kv.first << ":" << kv.second << endl;}*/
}

 (四) multimap

它和map区别就是可以插入重复键,但是他没有重载【】其他的用法都是一样。

 // 声明一个multimap变量multimap<string, int> mm;// 示例:向multimap中添加元素mm.insert(make_pair("apple", 1));mm.insert(make_pair("banana", 2));mm.insert(make_pair("apple", 3)); // 可以有重复的键// 示例:遍历multimapfor (const auto& kv : mm) {cout << kv.first << ": " << kv.second << endl;}return 0;
}

(五)set和map OJ题 

 1.692. 前K个高频单词 - 力扣(LeetCode)

 

class Solution {
public:struct Compare{bool operator()(const pair<string,int>& kv1, const pair<string,int>& kv2){return kv1.second > kv2.second || (kv1.second == kv2.second && kv1.first < kv2.first);} //次数最多的返回 或者次数相等相等的情况再根据字典序排序规则比较};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> countMap;for(auto& kv:words){countMap[kv]++; //插入+统计次数}vector<pair<string,int>> v(countMap.begin(),countMap.end()); //把数据方便vector这个容器 //为什么是vector 方便sort 关联式的容器 sort是排不了序的sort(v.begin(),v.end(),Compare());//sort排序不稳定 我们需要加仿函数自己控制排序vector<string> ret; //因为前面的v是键值对数据,我们再单独创建一个顺序表把first放到这个数组里再返回这个retfor(size_t i = 0; i<k; i++){ret.push_back(v[i].first);}return ret;}
};

 2.349. 两个数组的交集 - 力扣(LeetCode)

 

 

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {// 先去重set<int> s1;for(auto e : nums1){s1.insert(e);}set<int> s2;for(auto e : nums2){s2.insert(e);}// set排过序,依次比较,小的一定不是交集,相等的是交集auto it1 = s1.begin();auto it2 = s2.begin();vector<int> ret;while(it1 != s1.end() && it2 != s2.end()){//为什么是小的++ 大的那个数,可能是小的那个set里面也有一个同样的//这时走大的不就错过了?if(*it1 < *it2){it1++;}else if(*it2 < *it1){it2++;}else{ret.push_back(*it1);it1++;it2++;}}return ret;}
};

map和set 底层实现逻辑还没有讲,下篇预告AVL树 对应就是map的底层原理,关注我带你学习更多C++知识!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/794119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移动开发技术历史演化简介h5,跨平台,原生的各种技术实现方案的简单介绍

移动端的开发技术是指针对移动设备如智能手机和平板电脑等便携终端进行应用程序和服务创建的过程。本文将主要介绍一下移动端的开发技术的历史进化历程。讲述h5&#xff0c;跨平台&#xff0c;原生的各种技术实现方案和他们各自的优势与不足。 移动开发&#xff0c;不仅是编程技…

在Ubuntu系统下连接远程Ubuntu服务器

本篇文章介绍&#xff0c;如何在Ubuntu系统下连接远程Ubuntu系统并传输文件。 一. 连接远程Ubuntu服务器。 1. 打开命令行&#xff0c;输入 : sudo apt-get update &#xff0c; 对系统进行更新。 2. 安装 OpenSSH Server&#xff0c;输入 &#xff1a; sudo apt-get insta…

聊一聊电子邮件?

电子邮件是什么&#xff1f; 电子邮件是一种基于客户/服务器架构的应用。功能是实现人与人之间的交流。直到现在&#xff0c;电子邮件依然是当前因特网 注意&#xff1a;基于客户/服务器方式和基于B/S架构不一样&#xff01;客户/服务器表示的范围更广&#xff0c;当基于客户…

Python 网络请求:深入理解Requests库

目录 引言 一、Requests库简介 二、安装与基本使用 三、requests库的特性与优势 四、requests库在实际应用中的案例 1.get请求 2.post请求 3.超时重试 4.headers设置 5.session会话 6.携带cookie​​​​​​​ 7.携带代理​​​​​​​ 8.携带身份认证​​​​​…

爬虫 新闻网站 并存储到CSV文件 以红网为例 V1.0

爬虫&#xff1a;红网网站&#xff0c; 获取当月指定关键词新闻&#xff0c;并存储到CSV文件 V1.0 目标网站&#xff1a;红网 爬取目的&#xff1a;为了获取某一地区更全面的在红网已发布的宣传新闻稿&#xff0c;同时也让自己的工作更便捷 环境&#xff1a;Pycharm2021&#…

【CSS】浮动笔记及案例

CSS浮动 1. 认识浮动 float属性可以指定一个元素沿着左侧或者是右侧放置&#xff0c;允许文本和内联元素环绕它 float属性最初只使用文字环绕图片但却是早起CSS最好用的左右布局方案 绝对定位、浮动都会让元素脱标&#xff0c;以达到灵活布局的目的可以通过float属性让元素脱…

UE4_材质节点

UE4_材质节点 2017-12-07 13:56 跑九宫格 跑UV 评论(0)

arm裸机-1、定时器pwm

时钟配置 我们使用s3c2440&#xff0c;主频12M&#xff0c;查看用户手册 通过锁相环抬升到400MHZ&#xff0c;分成三条通路&#xff0c;通过HHDIVN和PDIVN配置频率比&#xff0c;这个频率比配置手册已经给出。 配置MPLL主频400Mhz&#xff0c; 通过这个公式算出MPLL s、p、m都…

hive 慢sql 查询

hive 慢sql 查询 查找 hive 执行日志存储路径&#xff08;一般是 hive-audit.log &#xff09; 比如&#xff1a;/var/log/Bigdata/audit/hive/hiveserver/hive-audit.log 解析日志 获取 执行时间 执行 OperationId 执行人 UserNameroot 执行sql 数据分隔符为 \001 并写入 hiv…

C语言——调试技巧

1.Debug和Release的介绍 Debug 通常称为调试版本&#xff0c;它包含调试信息&#xff0c;并且不作任何优化&#xff0c;便于程序员调试程序。Release 称为发布版本&#xff0c;它往往是进行了各种优化&#xff0c;使得程序在代码大小和运行速度上都是最优 的&#xff0c;以便用…

基于单片机的全自动洗衣机系统仿真设计

**单片机设计介绍&#xff0c;基于单片机的全自动洗衣机系统仿真设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的全自动洗衣机系统仿真设计概要是关于利用单片机技术实现全自动洗衣机控制功能的系统设计概述。以…

科东软件参加广州机器人产业联盟举办先进工业母机专家研讨会

工业母机是“制造机器的机器”&#xff0c;具有基础性、通用性、战略性特征&#xff0c;包括了减材切削机床、等材成形装备、增材制造装备及其控制系统等&#xff0c;是衡量国家工业水平和竞争力的重要标志。广东省作为全球知名的制造业基地&#xff0c;非常重视高端装备领域工…

有关字符串算法

例题一 解法&#xff1a; 算法思路&#xff08;两两⽐较&#xff09;&#xff1a; 我们可以先找出前两个的最⻓公共前缀&#xff0c;然后拿这个最⻓公共前缀依次与后⾯的字符串⽐较&#xff0c;这样就可以找出所有字符串的最⻓公共前缀。 例题二 解法&#xff08;中⼼扩散&am…

HuggingFace踩坑记录-连不上,根本连不上

学习 transformers 的第一步&#xff0c;往往是几句简单的代码 from transformers import pipelineclassifier pipeline("sentiment-analysis") classifier("We are very happy to show you the &#x1f917; Transformers library.") ""&quo…

Flask-RESTful 分析

Flask-RESTful 是一个 Flask 扩展&#xff0c;它为构建 RESTful API 提供了方便的工具和资源。它简化了创建 RESTful 服务的过程&#xff0c;允许开发者专注于业务逻辑而不是 HTTP 协议的细节。 资源&#xff08;Resources&#xff09;&#xff1a; Resource 类&#xff1a;是…

Java集合详解(一)-- List集合

1.集合简介 java集合可分为Set、List、Queue和Map四种体系。 Java集合就像一种容器&#xff0c;可以把多个对象&#xff08;实际上是对象的引用&#xff0c;但习惯上都称对象&#xff09;“丢进”该容器中。从Java 5 增加了泛型以后&#xff0c;Java集合可以记住容器中对象的数…

PW1503限流芯片:可达3A限流,保障USB电源管理安全高效

在电源管理领域&#xff0c;开关的性能直接关系到设备的稳定性和安全性。今天&#xff0c;我们将详细解析一款备受关注的超低RDS&#xff08;ON&#xff09;开关——PW1503。它不仅具有可编程的电流限制功能&#xff0c;还集成了多项保护机制&#xff0c;为各类电子设备提供了高…

解决在统信UOS Linux下缺乏zlib和jpeg库导致的安装Pillow报错问题

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、引言 今天在统信UOS Linux的Python3环境下安装Pillow遇到了问题&#xff0c;导致安装不成功&#xff0c;通过报错信息。 二、第一执行pip3 install pillow安装报错 为了提高效率&#xff0c;指向了清华…

Spring重点知识(个人整理笔记)

目录 1. 为什么要使用 spring&#xff1f; 2. 解释一下什么是 Aop&#xff1f; 3. AOP有哪些实现方式&#xff1f; 4. Spring AOP的实现原理 5. JDK动态代理和CGLIB动态代理的区别&#xff1f; 6. 解释一下什么是 ioc&#xff1f; 7. spring 有哪些主要模块&#xff1f;…

Spring-IoC 基于注解

基于xml方法见&#xff1a;http://t.csdnimg.cn/dir8j 注解是代码中的一种特殊标记&#xff0c;可以在编译、类加载和运行时被读取&#xff0c;执行相应的处理&#xff0c;简化 Spring的 XML配置。 格式&#xff1a;注解(属性1"属性值1",...) 可以加在类上…