C++中map和set的使用

在这里插入图片描述(图片来源于网络)

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻强烈推荐优质专栏: 🍔🍟🌯C++的世界(持续更新中)
🐻推荐专栏1: 🍔🍟🌯C语言初阶
🐻推荐专栏2: 🍔🍟🌯C语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:讲解C++中的新容器,set与map对于常用的接口介绍。
金句分享:
✨人攀明月不可得,月行却与人想随。✨

目录

  • 一、set
  • 1.1 set特点介绍
  • 1.2 set使用
    • 1.21 构造函数
    • 1.22 升/降序
    • 1.23 其他接口
      • (1) **容量(`capacity`)相关:**
      • (2)**Modifiers(修改)**
      • (3)**查找**
  • 二、map
  • 2.1 map的特点介绍
    • 2.2 map的使用
      • ✨构造函数
      • 🍔[ ]的作用
  • 三、实例
    • 🍭两个数组的交集
    • 🍔单词识别

一、set

1.1 set特点介绍

set的介绍
C++中的set是一个STL容器,它是一个自动排序的集合(即将数据存入set,我们通过迭代器顺序访问出来时,数据是有序的),内部使用红黑树(后面会讲解)来实现。它的特点是不允许重复元素,而且插入元素时自动进行排序。

set容器的特点

  1. 存入set后数据有序: set是按照一定次序存储元素的容器,迭代器迭代出来的数据是有序的。
  2. 数据唯一(可以用于去重):每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3. set在底层是用二叉搜索树(红黑树)实现的。
    注意:
  4. set中查找某个元素,时间复杂度为: l o g 2 n log_2 n log2n,因为底层是红黑树。

1.2 set使用

1.21 构造函数

在这里插入图片描述
(来源于:官方文档)

测试构造:

	//测试构造
	void test_Construct() {
    set<int> s1;//普通构造
    
   //迭代器构造
   //数组
    int arr[] = { 2,2,1,1,5,5,5,1,7,9,8,10 };
    set<int> s2(arr,arr+sizeof(arr)/sizeof(int));    //默认就是升序
    cout << "s2: ";
    for (auto it : s2) {
        cout << it << " ";
    }
    cout << endl;
	//vector
    vector<int> v = { 2,2,1,1,5,5,5,1,7,9,8,10 };
    set<int> s3(v.begin(), v.end());    //默认就是升序
    cout << "s3: ";
    for (auto it : s3) {
        cout << it << " ";
    }
    cout << endl;

    //拷贝构造
    set<int> s4(s3);
    cout << "s4: ";
    for (auto it : s3) {
        cout << it << " ";
    }
    cout << endl;
}

运行结果:

s2: 1 2 5 7 8 9 10
s3: 1 2 5 7 8 9 10
s4: 1 2 5 7 8 9 10

1.22 升/降序

void test_cmp() {
    //set 降序
    set<int, less<int>> s1;
    s1.insert(3);
    s1.insert(5);
    s1.insert(2);
    s1.insert(6);
    s1.insert(7);
    s1.insert(10);
    s1.insert(9);
    s1.insert(1);
    s1.insert(4);
    s1.insert(8);
    cout << "升序:s1: ";
    for (auto it : s1) {
        cout << it << " ";
    }
    cout << endl;

    //set升序
    set<int, greater<int>> s2;
    s2.insert({3,5,2,6,7,10,9,1,4,8});
    cout << "降序:s2: ";
    for (auto it : s2) {
        cout << it << " ";
    }
    cout << endl;
}

运行结果:

升序:s1: 1 2 3 4 5 6 7 8 9 10
降序:s2: 10 9 8 7 6 5 4 3 2 1

1.23 其他接口

(1) 容量(capacity)相关:

接口名介绍
empty( )检测set是否为空,空返回true,否则返回false
size()获取set中有效数据的个数

(2)Modifiers(修改)

在这里插入图片描述
在这里插入图片描述

接口名解释
insert向set中插入数据,可以是迭代器区间们也可以是单个的值
erase删除指定位置的数据(可以提供迭代器,也可以是元素值)
void swap (set& x);交换两个set
void clear();清除set中的数据

(3)查找

接口名解释
iterator find (const value_type& val) const;查找元素 ,返回该元素的迭代器
size_type count (const value_type& val) const;返回目标元素在set中出现的次数(由于set是不予讯重复元素的,所以这个接口意义不大)
	void test() {
    set<int, greater<int>> s1;
    s1.insert({ 3,5,2,6,7,10,9,1,4,8 });

    cout << "有效数据的个数: " << s1.size() << endl;
    cout << "是否为空容器:  " << s1.empty() << endl;
    //在set中意义不大的函数
    cout << "容器中元素3出现了:  " << s1.count(3) << endl;
    set<int>:: iterator it = s1.find(2);        //找到则返回这个元素的迭代器,没找到,则返回end()
    cout <<"find(2): "<< * it << endl;

    set<int, greater<int>> s2;
    s2.insert({ 1,5,8 });

    cout << "交换前:"<<endl;
    cout << "s1: ";
    for (auto it : s1) {
        cout << it << " ";
    }
    cout << endl;

    cout << "s2: ";
    for (auto it : s2) {
        cout << it << " ";
    }
    cout << endl;

    swap(s1, s2);

    cout << "交换后:" << endl;
    cout << "s1: ";
    for (auto it : s1) {
        cout << it << " ";
    }
    cout << endl;

    cout << "s2: ";
    for (auto it : s2) {
        cout << it << " ";
    }
    cout << endl;

    s1.clear();
    cout << "清除:s1: ";
    for (auto it : s1) {
        cout << it << " ";
    }
    cout << endl;
}

运行结果:

有效数据的个数: 10
是否为空容器: 0
容器中元素3出现了: 1
find(2): 2
交换前:
s1: 10 9 8 7 6 5 4 3 2 1
s2: 8 5 1
交换后:
s1: 8 5 1
s2: 10 9 8 7 6 5 4 3 2 1
清除:s1:

二、map

2.1 map的特点介绍

map是一个关联容器,它提供了一种存储键值对的方法。它是按照键(key)进行排序和存储的,键必须是唯一的,而值(value)可以重复。map通常使用红黑树实现,所以它的查找、插入和删除操作的时间复杂度都是O(log n)。

那么何为键值对?
键值对是一种常用的数据存储结构,由“键”和“值”两部分组成。其中,“键”是唯一的,用于标识数据,而“值”则是与键相关联的数据。
其实很简单,例如: {“apple”, “苹果”}

下面是pair大概实现:

template <typename T1, typename T2> 
struct pair {
    T1 first;		//键
    T2 second;		//值
    pair() : first(), second() {}
    pair(const T1& x, const T2& y): first(x), second(y) {}
    template <typename U1, typename U2>
    pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {}
    pair& operator=(const pair& rhs) {
        if (this != &rhs) {
            first = rhs.first;
            second = rhs.second;
        }
        return *this;
    }
};

2.2 map的使用

在这里插入图片描述
mapset的用法基本相同,只不过一个是键值对,一个是单个的值。
这里对于map就不过多介绍了。

✨构造函数

	void test_map() {
    // 构造空的map
    map<string, int> map1;
    cout << "map1:" << endl;
    for (auto it : map1) {
        cout << it.first << it.second << endl;
    }
    cout << endl;

    // 使用初始化列表构造
    map<string, string> map2{
        {"apple", "苹果"},
        {"banana", "香蕉"},
        {"orange", "橘子"}
    };
    cout << "map2:" << endl;
    for (auto it : map2) {
        cout << it.first << it.second << endl;
    }
    cout << endl;

    // 构造map并插入元素
    map<string, int> map3;
    map3.insert(pair<string, int>("panda", 1));
    map3.insert(make_pair("", 2));
    map3.insert(map<string, int>::value_type("monkey", 3));
    cout << "map3:" << endl;
    for (auto it : map3) {
        cout << it.first << it.second << endl;
    }
    cout << endl;
    cout << "空格对应的值:" << map3[""];
}

运行结果:

map1:

map2:
apple苹果
banana香蕉
orange橘子

map3:
2
monkey3
panda1

空格对应的值:2

🍔[ ]的作用

在这里插入图片描述

C++ 中,map 中的 [] 运算符可以用于访问和修改 map 中的元素,其作用如下:

  1. 若键值存在,返回对应的值;
  2. 若键值不存在,会与这个不存在的key和默认值构成一个键值对,自动插入默,并返回该默认值的引用。
	void test() {
    std::map<std::string, int> my_map;
    my_map["apple"] = 2;
    my_map["banana"] = 3;
    cout << "my_map 变化前" << endl;
    for (auto it : my_map) {
        cout << it.first << " : " << it.second << endl;
    }
    cout << endl;

    std::cout << my_map["apple"] << std::endl; // 输出 2
    std::cout << my_map["pear"] << std::endl;  // 输出默认值 0

    cout << "my_map 变化后" << endl;
    for (auto it : my_map) {
        cout << it.first << " : " << it.second << endl;
    }
    cout << endl;

}

运行结果:

my_map 变化前
apple : 2
banana : 3

2
0
my_map 变化后
apple : 2
banana : 3
pear : 0

在这里插入图片描述

注意map可以通过[key]访问对应的value

关于map,本篇就主要介绍这[ ]接口了。

三、实例

🍭两个数组的交集

(1)关于set的示例使用:
set在oj题中的应用
题目名称:两个数组的交集
题目链接: 传送门
(声明:题目来源于“力扣”)

题目描述
给定两个数组 nums1nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
在这里插入图片描述

解题思路:
将两个数组分别进set中去重得到s1s2,然后将其中一个与另一个比较,判断是否存在则是交集。

示例代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> ret;    //用于返回结构的数组
        //先通过set去重
        set<int> s1;
        for(int& it:nums1){
            s1.insert(it);
        }

        set<int> s2;
        for(int& it:nums2){
            s2.insert(it);
        }

        for(auto& it:s1){
            if(s2.count(it)){    //表示s1中的值在s2中可以找到
                ret.push_back(it);
            }
        }
        return ret;
    }
};

🍔单词识别

(2)关于map的使用

题目描述:
输入一个英文句子,把句子中的单词(不区分大小写)按出现次数按从多到少把单词和次数在屏幕上输出来,次数一样的按照单词小写的字典序排序输出,要求能识别英文单词和句号。

在这里插入图片描述

  1. 由于不区分大小写,可以先将字符串中所有的字母转化为小写。
  2. 将字符串按照空格划分,划分为一个个单词word。
  3. 将单词存入map,没出现一次单词,该单词的次数就+1;
  4. 最后按迭代器跑一遍即可。

示例代码:

#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;

int main() {
    string sentence;
    getline(cin, sentence);
    //全部转化为小写
    for (auto& it : sentence) {
        if (it >= 'A' && it <= 'Z') {
            it += 32;
        }
    }
    auto left = sentence.begin();
    auto right = left;
    map<string, int, less<string>> m;
    for (int i = 0; i < sentence.size(); i++) {
        right = sentence.begin();
        if (sentence[i] == ' ' || sentence[i] == '.')
        {
            right += i;
            string word(left, right);
            left = right + 1;
            m[word]++;
        }
    }

    for (auto& it : m) {
        cout << it.first << ":" << it.second << endl;
    }
    return 0;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

shardinig-JDBC二开-支持sharding-jdbc的配置文件接入到nacos

代码在 https://gitee.com/lbmb/mb-live-app 中 【mb-live-framework】 模块里面的【mb-live-framework-datasource-stater】 如果喜欢 希望大家给给star 项目还在持续更新中。 背景介绍&#xff1a; 因为近期在自己写一套直播项目。使用到了sharding-jdbc来做分库分表的组件…

Python第三方扩展库NumPy

Python第三方扩展库NumPy NumPy(Numerical Python&#xff0c;注意使用时全部小写 numpy) 是 Python 语言的一个扩展程序库&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供大量的数学函数库。 在Windows平台上安装numpy&#xff0c;可在cmd命令…

游戏设计模式

单列模式 概念 单例模式是一种创建型设计模式&#xff0c;可以保证一个类只有一个实例&#xff0c;并提供一个访问该实例的全局节点。 优点 可以派生&#xff1a;在单例类的实例构造函数中可以设置以允许子类派生。受控访问&#xff1a;因为单例类封装他的唯一实例&#xf…

学习笔记-李沐动手学深度学习(五)(14-15,数值稳定性、模型初始化和激活函数、Kaggle房价预测)

总结 14-数值稳定性&#xff08;梯度爆炸、梯度消失&#xff09; 尤其是对于深度神经网络&#xff08;即神经网络层数很多&#xff09;&#xff0c;最终的梯度就是每层进行累乘 理论 t&#xff1a;为第t层 y&#xff1a;不是之前的预测值&#xff0c;而是包括了损失函数L …

统一聚合支付系统一个支付系统包含微信支付宝支付接口可对外提供多个网站使用同一个支付系统的初探与逻辑图

#聚合支付# #小李子9479# 开发背景 作为一个合格的站长或者运营&#xff0c;基本上都有好几个网站&#xff0c;而变现的方式其中之一就是付费。经常使用的付费包含微信支付和支付宝支付。微信的jsapi支付需要使用到openid&#xff0c;而获取openid需要设置授权域名&#xff…

C#用TimeSpan的Days、Hours、Minutes及Seconds属性确定程序的运行时间

目录 一、TimeSpan结构的Days、Hours、Minutes及Seconds属性 1.Days属性 2.Hours属性 3.Minutes属性 4.Seconds属性 二、确定程序运行时间的方法 1.实例源码 2.生成效果 在程序设计过程中&#xff0c;经常需要在主窗体中动态地显示程序的运行时间。 一、TimeSpan结构的…

【Linux】-同步互斥的另一种办法-信号量

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

身份证也可以cisa远程考试

CISA CISM CRISC CGEIT ​只有身份证 ​没有护照 ​没有港澳通行证 ​也可以线上考试

python学习20

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

object detection的一些pre trained模型(视频可以实现一下)

https://www.youtube.com/watch?v2yQqg_mXuPQ 你的支持是我创作的源泉

CC++内存管理【非常详细,对新手友好】

文章目录 一、程序内存划分1.基础知识2. 堆栈的区别3. 题目练手 二、C语言中动态内存管理方式三、C中动态内存管理方式1. new/delete操作内置类型2. new/delete操作自定义类型 四、operator new和operator delete函数1. 汇编查看编译器底层调用2. 透过源码分析两个全局函数 五、…

老旧小区火灾频发,LoRa无线系统筑牢安全防线

近日&#xff0c;全国各地多个老旧小区火灾事故频发&#xff0c;从安微合肥南二环一老旧小区居民楼起火、上海金山区一小区居民楼火灾&#xff0c;到1月24日江西新余市特大火灾......都造成了不同程度的人员伤亡和财产损失&#xff0c;令人扼腕痛惜&#xff0c;教训十分深刻。 …

浅谈 ts的类型校验 经验分享

经验1&#xff1a; 【input"testVal $event.target.value"】会有一个ts报错&#xff1a;【“$event.target”可能为 “null”。】我们可以使用【input"testVal (<HTMLInputElement>$event.target).value"】解决ts报错<input type"text&quo…

C#-前后端分离连接mysql数据库封装接口

C#是世界上最好的语言 新建项目 如下图所示选择框红的项目 然后新建 文件夹 Common 并新建类文件 名字任意 文件内容如下 因为要连接的是mysql数据库 所以需要安装 MySql.Data.MySqlClient 依赖; using MySql.Data.MySqlClient; using System.Data;namespace WebApplication1.…

【Image captioning】论文阅读八—ClipCap: CLIP Prefix for Image Captioning_2021

中文标题&#xff1a;ClipCap: CLIP前缀用于图像描述&#xff08;ClipCap: CLIP Prefix for Image Captioning&#xff09; 文章目录 1. 介绍2. 相关工作3. 方法3.1 综述3.2 语言模型微调3.3 映射网络架构3.4 推理 4. 结果5. 结论 摘要&#xff1a;图像描述是视觉语言理解中的…

黑群晖屏蔽更新

黑群晖屏蔽更新 修改Host删除控制面板的红点和更新提示 修改Host ssh连接群晖后执行以下命令 sudo vim /etc/hosts按i键进入编辑模式 光标移动定位到最后一行后追加以下两行 127.0.0.1 update.synology.com 127.0.0.1 update7.synology.com按esc键&#xff0c;然后输入:wq并…

Nginx进阶篇【四】

Nginx进阶篇【四】 六、Nginx负载均衡6.1.负载均衡概述6.2.负载均衡的原理及处理流程6.3.负载均衡的作用6.4.负载均衡常用的处理方式6.4.1.方式一:用户手动选择6.4.2.方式二:DNS轮询方式6.4.2.1.DNS6.4.2.2.为某一个域名添加的IP地址&#xff0c;用2台服务器来做负载均衡6.4.2.…

ROS2学习笔记(0)开坑声明

0.前提 在做racecar的过程中发现已经有不少的开发者和公司开始从ros1转向ros2的怀抱了&#xff0c;刚好寒假在家&#xff0c;我就顺带试试看能不能学点ros2&#xff0c;刚好我有两辆车和主板可以双线开工&#xff08;是的&#xff0c;全是老师们赞助的&#xff0c;真的我哭死&…

Java面试题之序列化和反序列化

Java面试题之序列化和反序列化 文章目录 Java面试题之序列化和反序列化序列化和反序列化什么是序列化?什么是反序列化?如果有些字段不想进行序列化怎么办&#xff1f;常见序列化协议有哪些&#xff1f;为什么不推荐使用 JDK 自带的序列化&#xff1f; 文章来自Java Guide 用于…

Python初学者学习记录——python基础综合案例:数据可视化——地图可视化

一、基础地图使用 1、基础地图演示 2、基础地图演示——视觉映射器 from pyecharts.charts import Map from pyecharts.options import VisualMapOpts# 准备地图对象 map Map() # 准备数据 data [("北京市", 99),("上海市", 199),("湖南省", 2…