C++ 关联式容器详解:set、map 及其变体的深度剖析----《Hello C++ Wrold!》(19)--(C/C++)

前言

在 C++ 标准库中,容器是数据存储和操作的核心工具,而关联式容器凭借其高效的查找、插入和删除特性,在处理需要快速检索的数据时展现出独特的优势。set、multiset、map 和 multimap 作为 C++ 中常用的关联式容器,底层通常基于红黑树实现,这使得它们在保证数据有序性的同时,能将基本操作的时间复杂度控制在 O (log n) 级别,远超序列式容器在查找操作上的表现。

本文将系统地介绍这几类关联式容器的特性、类模板参数、构造函数及常用接口,深入剖析 set 与 map 在存储模型(k 模型与 k-v 模型)上的差异,以及 multiset、multimap 与对应基础容器在去重特性上的区别。此外,还将通过具体的作业案例,展示这些容器在实际问题中的应用,帮助读者理解如何根据场景选择合适的容器,以及如何高效地运用其接口解决问题。无论是对 C++ 初学者巩固容器知识,还是对有经验的开发者优化代码效率,本文都具有一定的参考价值。

set

set的类模板参数声明

在这里插入图片描述

set的构造函数声明

在这里插入图片描述

eg: set<int> s;

set常见的几个接口

operator =

begin end rbegin rend cbegin cend crbegin crend

empty size insert erase swap clear find

lower_bound:返回的是>=传入值的第一个值

upper_bound:返回的是>传入值的第一个值

equal_range:第一个迭代器返回的是第一个>=val的值的迭代器,第二个迭代器返回的是第一个>val的迭代器,没有的话,就返回end()那个的迭代器

(注意eg:是查找到的顺序,而不是插入的顺序,因为插入还会涉及到旋转)

在这里插入图片描述

count:返回的是里面值为val的个数

在这里插入图片描述

注意:1.没有operator[]

    2.`set`会自动排序和去重
    3.里面的`erase`的用法跟其他接口有点不同

在这里插入图片描述

而且,传值的话,如果里面没有这个值,是不会报错的;传迭代器,没有这个迭代器,是会报错的

  4.这里的`find`跟库函数里面的`find`的对比:
这里的find是二分查找--时间复杂度是O(logn)
库函数里面的find是暴力遍历--时间复杂度是O(n)

multiset

这个相较于set的区别就是,他不会去重而已;其他的接口跟set一模一样

上面的countequal_range一般只有multiset会用到

map

相比于set其实就是map是k-v模型,set是k模型

注意:set和multisetiterator迭代器其实也是const_iterator类型的,map则不是;但是他们都不能修改key

map的类模板参数声明

在这里插入图片描述

这里的Cmoparekey进去参与比较的

key的类型要是不支持比较大小的话,自己要写仿函数

map的构造函数声明

在这里插入图片描述

map常用的几个接口

operator =      operator[]
begin end  rbegin rend  cbegin cend  crbegin crend 
empty size
insert erase swap clear
find count lower_bound upper_bound equeal_range

其中的operator[]是传入key,返回value

其中的insert要重点讲解一下:

在这里插入图片描述

插入过程中比较的是key,所以key相同,value不同的是插入不进来的(map的话)

关于insert的返回值:

如果key已经在树里面,返回pair<树里面key所在节点的iterator,false>

如果key不在树里面,返回pair<新插入key所在节点的iterator,true>

一般常用的用法:

eg:C++98  
map1.insert(make_pair("string","字符串"))--一般用这个
map1.insert(pair<string,string>("string","字符串"))
C++11 多参数的构造函数隐式类型转换
map1.insert({"string","字符串"})

multimap

这个相较于map的区别就是,他不会去重而已;有俩个接口跟map不一样

1.multimap没有operator[]
2.multimapinsert的返回值跟map的不一样

在这里插入图片描述

注意:multimapunordered_map别搞混了

pair

在这里插入图片描述

这个类型可以用来存储两个类型的变量

eg:    pair<int,string>p1(1,"p");

如果想要自动能推导类型的话,要用make_pair

用法eg: make_pair(1,3)

pair也是支持比较大小的:(默认是升序)

是先比first,first一样就比second

引申:函数模板是可以自动推导类型的,但是类模板是不可以的!

作业部分

下列说法正确的是(A)
A.set中的某个元素值不能被直接修改
B.map和unordered_map都是C++11提供的关联式容器//map是C++98,unordered_map是C++11
C.因为map和set的底层数据结构相同,因此在实现时set底层实际存储的是<key, key>的键值对
//map和set底层结构都是红黑树,而其底层红黑树在实现时并没有区分是存k模型还是kv模型
D.map和multimap中都重载了[]运算符//multimap没有
下面关于set的说法正确的是(B)
A.set中一定不能存储键值对,只能存储key//set中可以存储键值对,实例化set时,将set中元素类型设置为pair即可
B.set可以将序列中重复性的元素去除掉

下面关于map和set说法错误的是(C)
A.map中存储的是键值对,set中只储存了key
B.map和set查询的时间复杂度都是O(log_2N)
C.map和set都重载了[]运算符
D.map和set底层都是使用红黑树实现的

力扣 349. 两个数组的交集

力扣  349. 两个数组的交集
做法:把两个组的值放到两个set中去重,然后依次比较: 
 1.小的++     2.相等的话,这个值就是交集值,储存这个值,然后同时++

引申:
处理差集的话:
把两个组的值放到两个set中去重,然后依次比较: 
1.小的就是差集里的值,储存这个值,然后小的++
2.相等的话就同时++
代码展示:
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int>v;
        set<int>s1(nums1.begin(),nums1.end());
        set<int>s2(nums2.begin(),nums2.end());
        auto it1 = s1.begin(); auto it2 = s2.begin();
        while(it1!=s1.end()&&it2!=s2.end())
        {
            if(*it1<*it2) it1++;
            else if(*it2<*it1)  it2++;
            else{
                v.push_back(*it1);
                it1++;it2++;
            }

        }
        return v;

    }
};

力扣 692. 前K个高频单词

力扣  692. 前K个高频单词
做法:先放map里面去统计次数,然后排序就可以了
(map不能用sort,因为map里面是双向迭代器,sort要求是随机访问迭代器)

这里排序有三种方法:
1.放vector里用sort
2.放vector里用stable_sort
3.用两个map->一个<string,int>map,一个<int,string>multimap(后者用来比较)

引申:要求按字典序排列时,通常是升序
比如:a在abc前面

引申:sort里面比较的那个重载的写法eg:

在这里插入图片描述

代码展示:
class Solution {
public:
struct Greater{
 bool operator() (pair<string,int>kv1,pair<string,int>kv2)
    {
        return kv1.second>kv2.second||(kv1.first<kv2.first&&kv1.second == kv2.second);
    }
};
   

    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int>Map;
        for(auto e:words) Map[e]++;

        vector<pair<string,int>>vv(Map.begin(),Map.end());
        stable_sort(vv.begin(),vv.end(),Greater());
       vector<string>v;
        for(int i = 0;i<k;i++)
        {
            v.push_back(vv[i].first);
        }
        return v;

    }
};

sort和stable_sort的区别

stable_sort更稳定,在两个值比较时是相等的话,sort不一定会按原来这俩个数的顺序去排,但是stable_sort就会

<think>好的,我需要帮助用户了解如何安装YOLO-World框架或库。首先,我应该确认用户的需求,他们可能是在本地环境中安装YOLO-World,以便进行对象检测或跟踪任务。根据提供的引用,特别是引用[2]和引用[3],YOLO-World与Ultralytics的YOLOv8集成,因此安装可能涉及YOLOv8的库。 首先,我应该检查Ultralytics官方文档是否有关于YOLO-World的具体安装步骤。由于引用[2]提到了使用YOLO-World模型进行跟踪的代码示例,安装步骤可能包括安装Ultralytics的Python包。用户可能需要使用pip安装ultralytics库,因为这是YOLOv8的官方实现。 接下来,用户可能需要安装其他依赖项,比如PyTorch,因为YOLO-World可能基于PyTorch框架。PyTorch的安装通常需要根据用户的CUDA版本选择合适的命令,或者使用CPU版本。因此,在步骤中应该包括安装PyTorch的部分,并给出相应的安装命令示例。 另外,引用[1]提到Hugging Face的Demo,但用户希望离线运行,所以不需要Hugging Face的安装,但可能需要确认是否有额外的依赖项,比如OpenCV或其他图像处理库。不过Ultralytics通常会自动处理这些依赖,所以可能只需安装ultralytics即可。 可能还需要验证安装是否成功,比如运行一个简单的导入语句或示例代码。例如,用户导入YOLO模型并加载预训练的权重,如引用[2]中的代码所示。如果出现错误,可能需要检查依赖项是否正确安装,或者是否有版本冲突。 此外,用户可能遇到常见问题,比如CUDA不可用或版本不匹配。应该提醒用户根据他们的硬件配置安装合适的PyTorch版本,并确保CUDA驱动已正确安装。 总结一下,安装步骤可能包括: 1. 安装PyTorch(根据系统环境选择版本)。 2. 使用pip安装ultralytics库。 3. 验证安装,运行示例代码。 需要确保这些步骤清晰,并且命令准确无误。同时,要参考提供的引用信息,特别是引用[2]中的代码示例,确保用户能够正确使用YOLO-World模型进行跟踪任务。此外,要提醒用户可能需要下载预训练权重,如yolov8s-world.pt,这些可能通过Ultralytics自动下载或需要手动下载。</think>### YOLO-World安装方法分步说明 #### 1. 安装PyTorch框架(基础依赖) YOLO-World基于PyTorch实现,需先安装适配的PyTorch版本。根据硬件选择以下命令: ```bash # CPU版本 pip install torch torchvision torchaudio # CUDA 11.x版本(NVIDIA显卡) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # Apple Silicon版本 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu ``` #### 2. 安装Ultralytics库(核心组件) 通过PyPI安装官方维护的YOLO-World支持库: ```bash pip install ultralytics ``` #### 3. 验证安装 创建Python脚本执行以下代码: ```python from ultralytics import YOLO model = YOLO("yolov8s-world.pt") # 自动下载预训练权重 print(model.info()) # 输出模型结构信息 ``` #### 4. 测试视频推理(可选验证) ```bash yolo track model=yolov8s-world.pt source="your_video.mp4" ``` [!NOTE] - 首次运行会自动下载预训练权重(约67MB),存放路径为`~/.cache/ultralytics` - 若需自定义类别,参考官方文档修改`model.set_classes(["class1", "class2"])`[^3]
评论 86
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值