0

0

C++如何利用std::binary_search优化大规模有序数据的检索?(搜索优化)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-03-03 13:33:10

|

746人浏览过

|

来源于php中文网

原创

std::binary_search仅适用于存在性判断,无法定位元素位置;实际检索应使用std::lower_bound或std::upper_bound获取迭代器,支持插入点定位、频次统计等,且保持o(log n)复杂度。

c++如何利用std::binary_search优化大规模有序数据的检索?(搜索优化)

std::binary_search 为什么不能直接替代手写二分?

它只返回 bool,不告诉你元素在哪——查到了是 true,没查到就是 false,连插入位置都给不了。真要拿来做检索主逻辑,多数时候你其实需要的是下标或迭代器,而不是“有没有”。

常见错误现象:std::binary_search 返回 true 后,再用 std::find 扫一遍找位置,白费 O(n) 时间;或者误以为它能返回匹配点,结果后续操作崩溃。

  • 真正该用 std::lower_boundstd::upper_bound:它们返回迭代器,且保持 O(log n) 复杂度
  • std::binary_search 仅适合纯存在性判断,比如校验数据完整性、预检条件
  • 所有标准算法都要求容器已严格升序(operator 满足严格弱序),若用自定义比较器,必须全程一致

用 std::lower_bound 查找第一个 ≥ target 的位置

这是实际检索中最常用的操作:定位插入点、统计频次、实现范围查询的起点。它比 std::binary_search 多做一点点事,但价值翻倍。

使用场景:去重数组中找某值首次出现位置;构建离散化映射表;配合 std::upper_bound 算区间长度。

立即学习C++免费学习笔记(深入)”;

示例:

NetShop网店系统
NetShop网店系统

NetShop软件特点介绍: 1、使用ASP.Net(c#)2.0、多层结构开发 2、前台设计不采用任何.NET内置控件读取数据,完全标签化模板处理,加快读取速度3、安全的数据添加删除读取操作,利用存储过程模式彻底防制SQL注入式攻击4、前台架构DIV+CSS兼容IE6,IE7,FF等,有利于搜索引挚收录5、后台内置强大的功能,整合多家网店系统的功能,加以优化。6、支持三种类型的数据库:Acces

下载
std::vector<int> arr = {1, 2, 2, 2, 3, 4, 4};
auto it = std::lower_bound(arr.begin(), arr.end(), 2);
// it 指向第一个 2,即 arr[1]
  • 参数顺序固定:begin, end, value,不能颠倒;比较器要传在最后,不是第三个参数
  • 若 target 大于所有元素,返回 arr.end(),务必检查是否越界再解引用
  • std::vectorstd::array 等支持随机访问的容器,底层是真正的二分;但对 std::list,它退化为线性查找(别这么干)

std::lower_bound 和 std::upper_bound 配合统计重复元素个数

有序数据里查某个值出现了几次,不用遍历,两行搞定。这是 std::binary_search 完全做不到的事。

性能影响:O(log n) 固定开销,和重复数量无关;而手写循环统计最坏 O(n)。

示例:

std::vector<int> arr = {1, 2, 2, 2, 3, 4, 4};
auto l = std::lower_bound(arr.begin(), arr.end(), 2);
auto u = std::upper_bound(arr.begin(), arr.end(), 2);
int count = std::distance(l, u); // 得到 3
  • std::upper_bound 返回第一个 > target 的位置,不是 ≥ ——这点和 lower_bound 的语义差一个等号,极易混淆
  • 如果 target 不存在,lower_bound == upper_bounddistance 为 0,安全
  • 不要对 std::setstd::map 用这个技巧:它们提供 count() 成员函数,但底层仍是 O(log n),且更简洁

自定义比较器时最容易漏掉的三个细节

一旦数据不是基础类型或排序规则特殊,比如按绝对值排、按字符串长度排、或结构体按某字段排,std::lower_bound 就必须带比较器——而且得带对。

常见错误现象:invalid comparator 运行时报错;查找结果偏移;甚至触发 undefined behavior。

  • 比较器必须是**严格弱序**:不能有 a ,也不能同时满足 <code>a 和 <code>b
  • 调用时比较器要传在第四个参数位:lower_bound(begin, end, val, cmp),不是第三个
  • 容器本身也得用同一套比较器构建(比如 std::set<t cmp></t>),否则数据物理顺序和算法预期不一致

复杂点在于:同一个容器,不同查找目标可能需要不同比较逻辑,但标准算法不支持运行时切换;这时候要么预建多个视图,要么改用 std::equal_range + 自定义谓词封装——但别硬塞进一个函数里试图通用。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

201

2023.11.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

678

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

219

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1561

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

645

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1108

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1082

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

187

2025.07.29

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

0

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 10.5万人学习

C 教程
C 教程

共75课时 | 5.1万人学习

C++教程
C++教程

共115课时 | 20.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号