STL容器搜索:当直接访问STL容器时,如何执行有效和正确的搜索?

news2025/1/13 7:40:08

在访问STL容器时进行搜索

  • 一、简介
  • 二、std::vector, std::deque, std::list
  • 三、std::map, std::multimap, std::set, std::multiset
  • 四、std::string
  • 六、总结

一、简介

本文主要了解如何在直接访问c++容器时高效地进行搜索。在STL容器中搜索,要牢记一个原则:如果可以的话,最好使用容器方法来搜索而不是使用外部算法接口。

有三个原因:

  • 它更快:在排序的容器中,所有方法都受益于排序集合中的快速对数搜索。此外,std::string方法实现了最优算法,并受益于字符串的内部表示。
  • 它更自然:std::mapstd::multimap方法可以直接搜索键,而不像算法那样必须查找std::pair< key, Value>,因为它们的迭代器可以直接指向。
  • 它在某些情况下更正确:在排序容器(如mapset)中,所有方法都使用等价而不是相等,而某些算法(如std::countstd::find使用相等)则不是这样。

现在让我们通过研究如何将它应用到 STL 提供的各种容器来深入了解更多细节。

二、std::vector, std::deque, std::list

这些容器没有公开任何与搜索相关的方法,只能通过算法来搜索。

三、std::map, std::multimap, std::set, std::multiset

这些容器有5个类方法,它们与一些算法共享它们的名称:count, find, equal_range, lower_boundupper_bound。在上一篇文章中有讲解过这些算法。

这些方法和算法的比较:

容器方法比算法更正确?比算法还快?比算法更自然?
count
find
equal_range相同
lower_bound相同
upper_bound相同
  • 更好的正确性是因为使用了等效而不是相等。
  • 更好的性能来自于为序列容器对元素进行排序这一事实。对于关联容器来说,这是因为它们的迭代器不是随机访问的,所以算法不能通过直接跳过所需的元素来执行分割(它们必须从头开始并向上移动到它们的位置),而容器的内部没有这种约束。
  • 它们对于映射来说更自然,因为传递给各种方法的参数是一个键,而不是std::pair<key, Value>

注意,没有与std::binary_search等价的容器方法。检查容器中是否存在一个键:

  • 对于std::mapstd::set:比较find的结果与end迭代器的结果。或者使用count方法。count作为方法不会引起任何性能问题,因为,像find一样,它在第一个与搜索的键相等的键处停止(因为根据std::mapstd::set的定义,只能有一个键与搜索的键相等)。
  • 对于std::multimapstd::multiset:因为count不会在第一个与搜索的键相等的键处停止,所以find在这里比count有优势。

std::multimapstd::multiset中,find方法返回与搜索值相等的任何元素,而不一定是第一个元素。如果确实需要第一个元素,可以使用equal_range,因为它具有简单的接口;或者,如果觉得equal_range太慢(因为它显示了整个范围),而只是需要第一个元素,那么可以使用lower_bound。但是,lower_bound同样也有它的缺点,也必须付出代价。

四、std::string

string实际上有24个搜索方法。它们被分成6组,每组有4个重载。对于所有组,4个重载的形式为:

  • 搜索由std::string给出的字符串。
  • 搜索由char*和size给出的字符串。
  • 搜索由char*给出的字符串(止于null字符)。
  • 搜索一个字符。

并且所有4个重载都以搜索字符串中的起始位置作为参数,默认值为0(从字符串的开头开始搜索)。

以下是6组方法:

  1. find 函数:用于从字符串中查找给定子字符串 str 的第一个匹配项。它返回子字符串在当前字符串中的位置索引,如果找不到则返回 std::string::npospos 参数是可选的,用于指定搜索的起始位置,默认为 0。

    size_t find(const std::string& str, size_t pos = 0) const;
    
  2. rfind 函数:与 find 函数类似,但它从字符串的末尾开始向前搜索子字符串 str 的最后一个匹配项。它返回子字符串在当前字符串中的位置索引,如果找不到则返回 std::string::npospos 参数是可选的,用于指定搜索的起始位置,默认为 std::string::npos,表示从末尾开始搜索。

    size_t rfind(const std::string& str, size_t pos = npos) const;
    
  3. find_first_of 函数:用于从字符串中查找与给定字符串 str 中的任何字符匹配的第一个字符。它返回找到的字符在当前字符串中的位置索引,如果找不到则返回 std::string::npospos 参数是可选的,用于指定搜索的起始位置,默认为 0。

    size_t find_first_of(const std::string& str, size_t pos = 0) const;
    
  4. find_last_of 函数:与 find_first_of 函数类似,但它从字符串的末尾开始向前搜索与给定字符串 str 中的任何字符匹配的最后一个字符。它返回找到的字符在当前字符串中的位置索引,如果找不到则返回 std::string::npospos 参数是可选的,用于指定搜索的起始位置,默认为 std::string::npos,表示从末尾开始搜索。

    size_t find_last_of(const std::string& str, size_t pos = npos) const;
    
  5. find_first_not_of 函数:用于从字符串中查找第一个不在给定字符串 str 中的字符。它返回找到的字符在当前字符串中的位置索引,如果找不到则返回 std::string::npospos 参数是可选的,用于指定搜索的起始位置,默认为 0。

    size_t find_first_not_of(const std::string& str, size_t pos = 0) const;
    
  6. find_last_not_of 函数:与 find_first_not_of 函数类似,但它从字符串的末尾开始向前搜索第一个不在给定字符串 str 中的字符。它返回找到的字符在当前字符串中的位置索引,如果找不到则返回 std::string::npospos 参数是可选的,用于指定搜索的起始位置,默认为 std::string::npos,表示从末尾开始搜索。

    size_t find_last_not_of(const std::string& str, size_t pos = npos) const;
    

在线性时间内实现字符串算法并不容易。string方法以最佳方式实现它们,当在字符串中搜索某些内容时,可以直接使用容器的方法。

六、总结

本文系统地介绍了在直接访问STL容器时执行有效和正确搜索的方法。通过理解STL容器的内部机制和使用适当的搜索技巧,可以提高代码的性能和可读性。关键要点包括使用迭代器和成员函数进行搜索,利用算法库提供的函数进行查找,以及根据不同的容器类型选择最佳搜索方法。通过掌握本文提供的技术和原则,读者将能够在使用STL容器时更加自信地进行搜索操作,提高代码的质量和效率。

在这里插入图片描述

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

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

相关文章

禾赛面经分享

前言 禾赛的linux开发工程师&#xff08;实习&#xff09;&#xff0c;base是上海&#xff0c;以下是面试遇到的一些问题。 目录 前言题目与答案C语言部分嵌入式相关手撕题 题目与答案 C语言部分 static关键字的作用 static修饰局部变量时&#xff1a;①改变了其存储位置&…

基础知识集合

https://blog.csdn.net/sheng_q/category_10901984.html?spm1001.2014.3001.5482 epoll 事件驱动的I/O模型&#xff0c;同时处理大量的文件描述符 内核与用户空间共享一个事件表&#xff1a;监控的文件描述符以它们的状态&#xff0c;当状态变化&#xff0c;内核将事件通知给…

【分治】Leetcode 库存管理 III

题目讲解 LCR 159. 库存管理 III 本题的含义就是让求出最小的k个数 算法讲解 class Solution { public:void my_qsort(vector<int>& nums, int l, int r){if(l > r) return ;int i l, left l-1, right r1;int key nums[rand() % (r - l 1) l];//完成分三…

大数据真题讲解系列——拼多多数据分析面试题

拼多多数据分析面试题&#xff1a;连续3次为球队得分的球员名单 问题&#xff1a; 两支篮球队进行了激烈的比赛&#xff0c;比分交替上升。比赛结束后&#xff0c;你有一个两队分数的明细表&#xff08;名称为“分数表”&#xff09;。表中记录了球队、球员号码、球员姓名、得…

hv第一坑:定时器

错误代码 重试策略&#xff1a;一次延迟1s,最长30s直至事件成功。 int try_count 0;//do something if(not success)m_loop->setTimerInLoop((try_count > 30 ? 30: try_count) *1000 , cb, INFINITE, 0x100);表现现象 cpu 爆了内存爆了 总结原因 hv内部代码bug&…

Maven通过flatten-maven-plugin插件实现多模块版本统一管理

正文 起因是公司开始推代码版本管理的相关制度&#xff0c;而开发过程中经常使用多模块构建项目&#xff0c;每次做版本管理时都需要对每个模块及子模块下的pom文件中parent.version和模块下依赖中的version进行修改&#xff0c;改的地方非常多&#xff0c;且非常容易漏。为此…

如何用Python构建一个生产级别的电影推荐系统 - 机器学习手册

构建项目是彻底学习概念并发展必要技能的最有效方式之一。 项目使您沉浸在现实世界的问题解决中&#xff0c;巩固您的知识&#xff0c;并培养批判性思维、适应能力和项目管理专业知识。 本指南将带您逐步构建一个根据用户喜好量身定制的电影推荐系统。我们将利用一个庞大的包…

20240419,继承,多态

土豆的老家陕西安康&#xff01;怪舒服的咯&#xff0c;广西一眼望去全是房子啦&#xff0c;小时候一眼开敞水田再也回不来啦 目录 五&#xff0c;继承 5.1 基本语法 5.2 继承方式 5.3 继承中的对象模型 5.4 构造和析构顺序 5.5 同名成员处理 5.6 同名静态成员处理 5.…

c#+unity基础

序列化&#xff1a; [SerializeField]&#xff0c;点不出来&#xff0c;只能在面板上显示绑定游戏物体 //公有隐藏 特有函数 特有函数&#xff1a;不需要调用&#xff0c;自动执行 Awake最先执行->OnEable 面向对象思想 面向对象思想&#xff1a;分为具体对象和抽象对…

从预训练损失的角度,理解语言模型的涌现能力

原文&#xff1a;Understanding Emergent Abilities of Language Models from the Loss Perspective 摘要 本文从预训练损失的角度重新审视语言模型的涌现能力&#xff0c;挑战了以往以模型大小或训练计算量为标准的观念。通过实验&#xff0c;作者发现预训练损失是预测下游任…

【算法】合并两个有序链表

本题来源---《合并两个有序链表》 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] /*** Definition for singl…

JavaSE——常用API进阶二(6/8)-ZoneId、ZoneDateTime、Instant(常见方法、用法示例)

目录 ZoneId 常见方法 用法示例 ZoneDateTime 常见方法 用法示例 Instant 常见方法 用法示例 如果在开发中我们有这样的需求&#xff1a;我们的系统需要获取美国现在的时间&#xff0c;或者其他地区的时间给用户观看&#xff0c;或者进行一些处理&#xff0c;那应该怎…

循环开关定时器(Smart PLC梯形图代码)

很多设备不需要复杂的逻辑时序控制,只需要实现简单的循环定时开关功能,对于这样的控制我们可以利用定时器组合去实现,但是如果系统里需要循环定时控制的设备比较多,那我们建议大家编写一个这样的循环定时开关功能块,SMART PLC循环开关定时器还可以参考下面文章链接 1、周…

短视频批量采集提取软件|视频关键词下载工具

短视频批量采集软件&#xff1a;快速抓取、高效下载 一、开发背景 随着短视频平台的兴起&#xff0c;获取并分析相关视频内容已成为许多业务的必要步骤。然而&#xff0c;传统的手动方式无法满足快速、批量获取的需求&#xff0c;因此我们开发了一款专业的短视频批量采集软件。…

FreeRTOS时间管理

FreeRTOS时间管理 主要要了解延时函数&#xff1a; 相对延时&#xff1a;指每次延时都是从执行函数vTaskDelay()开始&#xff0c;直到延时指定的时间结束。 绝对延时&#xff1a;指将整个任务的运行周期看成一个整体&#xff0c;适用于需要按照一定频率运行的任务。 函数 vTa…

springcloud第4季 springcloud-alibaba之sentinel

一 sentinel介绍 1.1 sentinel作用 sentinel是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障服务的稳定性。 1.2 组成部分 sen…

A Geolocation Databases Study(2011年)第五部分:Evalution Model

下载地址:A Geolocation Databases Study | IEEE Journals & Magazine | IEEE Xplore 被引次数:195 Shavitt Y, Zilberman N. A geolocation databases study[J]. IEEE Journal on Selected Areas in Communications, 2011, 29(10): 2044-2056. 5. Discussion 在我们讨…

Jenkins的安装和部署

文章目录 概述Jenkins部署项目的流程jenkins的安装启动创建容器进入容器浏览器访问8085端口 Jenkins创建项目创建example项目 概述 Jenkins&#xff1a;是一个开源的、提供友好操作界面的持续集成&#xff08;CLI&#xff09;工具&#xff0c;主要用于持续、自动构建的一些定时…

什么是知乎知+广告推广?

知乎作为中国领先的知识分享社区和高质量用户群体汇聚地&#xff0c;其广告价值日益凸显&#xff0c;其中&#xff0c;“知”作为知乎官方推出的创新广告形式&#xff0c;正逐渐成为品牌与消费者深度连接的重要桥梁。知广告推广不仅局限于传统意义上的硬性推广&#xff0c;更强…

C语言中与内存操作有关的一些函数

前提 最近在使用C语言在开发项目时&#xff0c;要对内存进行操作。刚开始写的时候有一点迷糊&#xff0c;看了一些东西后才发现为什么说指针是C语言的灵魂&#xff0c;因为它可以对内存直接进行操作&#xff0c;多么帅的事情&#xff0c;真的是太帅了。 malloc 声明在头文件…