C++二分查找法,upper_bound与lower_bound

news2024/10/23 0:48:36

文章目录

  • 什么是二分查找法
  • 什么是upper_bound
  • lower_bound

什么是二分查找法

二分查找法(Binary Search)是一种在有序数组中查找特定元素的搜索算法。二分查找法的工作原理是通过不断将搜索区间分成两半来缩小查找的范围,每次比较中间元素与目标值,根据比较结果决定是继续在左半边还是右半边查找。
二分查找法的基本步骤如下:

  1. 首先,确定数组的中间位置。
  2. 比较中间位置的元素与目标值。
  3. 如果中间位置的元素正好是目标值,则搜索过程结束。
  4. 如果目标值小于中间位置的元素,则在数组的左半边继续搜索。
  5. 如果目标值大于中间位置的元素,则在数组的右半边继续搜索。
  6. 重复上述步骤,直到找到目标值或搜索范围为空。
    在 C++ 中,你可以使用标准库中的 std::binary_search 函数来检查数组或容器中是否存在某个元素,或者你可以自己实现二分查找法。以下是使用 std::binary_search 的示例:
#include <iostream>
#include <vector>
#include <algorithm> // 包含 std::binary_search
int main() {
    std::vector<int> vec = {1, 3, 5, 7, 9, 11, 13, 15};
    int target = 7;
    // 使用 std::binary_search 查找元素
    bool found = std::binary_search(vec.begin(), vec.end(), target);
    if (found) {
        std::cout << "Element " << target << " found in the vector." << std::endl;
    } else {
        std::cout << "Element " << target << " not found in the vector." << std::endl;
    }
    return 0;
}

如果你想自己实现二分查找法,以下是代码示例:

#include <iostream>
#include <vector>
int binarySearch(const std::vector<int>& vec, int target) {
    int left = 0;
    int right = vec.size() - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2; // 防止溢出
        if (vec[mid] == target) {
            return mid; // 找到目标值,返回索引
        } else if (vec[mid] < target) {
            left = mid + 1; // 在右侧子数组中查找
        } else {
            right = mid - 1; // 在左侧子数组中查找
        }
    }
    return -1; // 未找到目标值,返回 -1
}
int main() {
    std::vector<int> vec = {1, 3, 5, 7, 9, 11, 13, 15};
    int target = 7;
    int index = binarySearch(vec, target);
    if (index != -1) {
        std::cout << "Element " << target << " found at index " << index << "." << std::endl;
    } else {
        std::cout << "Element " << target << " not found in the vector." << std::endl;
    }
    return 0;
}

在这个示例中,binarySearch 函数实现了二分查找算法,并返回目标值在数组中的索引(如果找到的话),或者返回 -1(如果没有找到)。

什么是upper_bound

upper_bound 是 C++ 标准库中的一个函数,它用于在已排序的序列(例如 std::vectorstd::dequestd::array 或其他支持随机访问迭代器的容器)中查找第一个大于特定值的元素的位置。当你调用 upper_bound 时,它返回一个指向该元素的迭代器,如果不存在这样的元素,则返回指向序列末尾的迭代器(即 end())。
具体来说,upper_bound 的功能如下:

  • 它在指定的迭代器范围 [first, last) 内进行二分查找。
  • 它寻找第一个位置,使得该位置上的元素大于给定的值 value
  • 如果所有元素都不大于 value,则返回 last(一个指向序列末尾的迭代器)。
  • 如果找到了这样的元素,它返回一个指向该元素的迭代器。
    这个函数要求序列在 [first, last) 范围内是有序的,且序列至少部分排序为非降序(即元素可以相等,但不能出现后面的元素小于前面的元素)。
    使用 upper_bound 需要包含 <algorithm> 头文件,并且它通常与 std::sort 或其他排序函数配合使用,以确保序列是有序的。
    在 C++ 中,upper_bound 是标准库中的一个函数,它用于在有序序列中查找第一个大于特定值的元素的位置。该函数定义在头文件 <algorithm> 中。下面是对 upper_bound(a.begin(), a.end(), x) 的详细解释:
  • a.begin(): 这是容器 a 的开始迭代器,指向容器中的第一个元素。
  • a.end(): 这是容器 a 的结束迭代器,指向容器中最后一个元素的下一个位置。
  • x: 这是你要在容器 a 中查找的值。
    函数 upper_bound 的行为如下:
  1. 它在区间 [a.begin(), a.end()) 中查找。
  2. 它寻找第一个位置,使得该位置上的元素大于 x
  3. 如果所有元素都不大于 x,则返回 a.end()
    返回值:
  • 如果找到了这样的元素,upper_bound 返回一个指向该元素的迭代器。
  • 如果没有找到,它返回一个指向 a.end() 的迭代器。
    示例:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    std::vector<int> a = {1, 2, 4, 4, 6, 8};
    int x = 4;
    auto it = upper_bound(a.begin(), a.end(), x);
    if (it != a.end()) {
        std::cout << "第一个大于 " << x << " 的元素是:" << *it << std::endl;
    } else {
        std::cout << "没有找到大于 " << x << " 的元素。" << std::endl;
    }
    return 0;
}

在这个例子中,upper_bound 将返回指向第一个 6 的迭代器,因为 6 是第一个大于 4 的元素。如果 x8 或更大的值,upper_bound 将返回 a.end()

lower_bound

C++ 标准库中也有 lower_bound 函数,它与 upper_bound 函数非常相似,但是它们的用途略有不同。lower_bound 用于在已排序的序列中查找第一个不小于(即大于或等于)特定值的元素的位置。
以下是 lower_bound 函数的基本行为:

  • 它在指定的迭代器范围 [first, last) 内进行二分查找。
  • 它寻找第一个位置,使得该位置上的元素不小于给定的值 value
  • 如果所有元素都小于 value,则返回 last(一个指向序列末尾的迭代器)。
  • 如果找到了这样的元素,它返回一个指向该元素的迭代器。
    upper_bound 不同的是,lower_bound 寻找的是第一个大于或等于特定值的元素,而 upper_bound 寻找的是第一个大于特定值的元素。
    lower_bound 的使用也需要包含 <algorithm> 头文件,并且序列必须是有序的。
    下面是 lower_bound 的一个简单示例:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    std::vector<int> a = {1, 2, 4, 4, 6, 8};
    int x = 4;
    auto it = lower_bound(a.begin(), a.end(), x);
    if (it != a.end()) {
        std::cout << "第一个大于或等于 " << x << " 的元素是:" << *it << std::endl;
    } else {
        std::cout << "没有找到大于或等于 " << x << " 的元素。" << std::endl;
    }
    return 0;
}

在这个例子中,lower_bound 将返回指向第一个 4 的迭代器,因为 4 是第一个不小于 4 的元素。如果 x1 或更小的值,lower_bound 也将返回指向第一个 1 的迭代器。如果 x9 或更大的值,lower_bound 将返回 a.end()

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

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

相关文章

windows中命令行批处理脚本学习

目录 一 基础知识二 常见命令1. 输出 echo2. 注释 rem .... %...% :: goto if (10) ()3. 变量 set4. 获取参数 %数字 %*5. 退出 exit6. 复制 copy7.读取输出文件内容 type8. 帮助 命令xxx /?9.等待当前命令运行结束后,才执行下一条命令 call10. 修改字体编码 chcp11. 特殊变量…

集合框架16:HashMap的使用

视频链接&#xff1a;13.35 HashMap使用&#xff08;1&#xff09;_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1zD4y1Q7Fw?spm_id_from333.788.videopod.episodes&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5&p35 1.创建Student类&#xff0c;添加无参构造…

UML之用例图详解

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 零、什么是用例图 用例图&#xff08;Use Case Diagram&#xff09;是UML中一种重要的图表类型&#xff0c;它主要用于描述系统的功能性需求&am…

Java使用HttpClient5实现发送HTTP请求

Java 实现发送 HTTP 请求&#xff0c;系列文章&#xff1a; 《Java使用原生HttpURLConnection实现发送HTTP请求》 《Java使用HttpClient5实现发送HTTP请求》 《SpringBoot使用RestTemplate实现发送HTTP请求》 1、HttpClient5 的介绍 HttpClient5 是 Apache HttpComponents 项目…

文件处理新纪元:微信小程序的‘快递员’与‘整理师’

嗨&#xff0c;我是中二青年阿佑&#xff0c;今天阿佑将带领大家如何通过巧妙的文件处理功能&#xff0c;让用户体验从‘杂乱无章’到‘井井有条’的转变&#xff01; 文章目录 微信小程序的文件处理文件上传&#xff1a;小程序的“快递服务”文件下载&#xff1a;小程序的“超…

植物大战僵尸杂交版游戏分享

植物大战僵尸杂交版游戏下载&#xff1a;夸克网盘分享 无捆绑之类的隐形消费&#xff0c;下载即玩

vue3 解决背景图与窗口留有间隙的问题

需要实现一个登录界面&#xff0c;login.vue的代码如下&#xff1a; <script> import { ref } from vue;export default {setup() {return {};}, }; </script><template><div id"login-container" class"login-container"><di…

Taro构建的H5页面路由切换返回上一页存在白屏页面过渡

目录 项目背景&#xff1a;Taro与Hybrid开发问题描述&#xff1a;白屏现象可能的原因包括&#xff1a; 解决方案解决后的效果图 其他优化方案可参考&#xff1a; 项目背景&#xff1a;Taro与Hybrid开发 项目使用Taro框架同时开发微信小程序和H5页面&#xff0c;其中H5页面被嵌…

Nodes 节点

Goto Tree List 树列表 Nodes 节点 Tree List 节点是组织成树状层次结构的数据行。 Add New Nodes 添加新节点 如果 Tree List 具有数据源&#xff0c;则会自动生成节点&#xff08;TreeListNode 类对象&#xff09;。要在未绑定模式下添加节点&#xff0c;请调用“树列表设…

【K8S系列】Kubernetes Pod节点Pending状态及解决方案详解【已解决】

在 Kubernetes 中&#xff0c;Pod 的状态为 Pending 表示 Pod 已被创建&#xff0c;但尚未被调度到节点上&#xff0c;或者已调度到节点上但容器尚未开始运行。这一状态常常是因为某些条件未满足&#xff0c;导致 Pod 无法正常启动。以下是对 Pending 状态的详细分析及解决方案…

自由学习记录(12)

综合实践 2D的Shape&#xff0c;Tilemap都要导包的&#xff0c;编辑器也要导包&#xff0c;。。和2d沾边的可能3d都要主动导包 应该综合的去运用&#xff0c;不见得Tilemap就很万能&#xff0c;如果要做什么顶方块的有交互反应的物体&#xff0c; 那直接拖Sprite会更方便一些…

APIJSON 为零代码提供了新的思路

APIJSON 核心概念 APIJSON 是一种用于构建 RESTful API 的 JSON 格式&#xff0c;它提供了一种标准化的方式来定义和处理 API 请求和响应。APIJSON 的设计目标是简化前端和后端之间的数据交互&#xff0c;减少开发工作量&#xff0c;提高开发效率。 在线解析 自动生成文档&am…

【SpringBoot】16 文件上传(Thymeleaf + MySQL)

Gitee仓库 https://gitee.com/Lin_DH/system 介绍 文件上传是指将本地的图片、视频、音频等文件上传到服务器&#xff0c;供其他用户浏览下载的过程&#xff0c;文件上传在日常项目中用的非常广泛。 实现代码 第一步&#xff1a;在配置文件新增如下配置 application.yml s…

docker-compose-lnmp-wordpress

使用 docker-compose 在 CentOS 7 上编写并部署 LNMP (Linux, Nginx, MySQL, PHP) 环境的 YAML 文章目录 部署步骤&#xff1a;1. 安装 Docker 和 Docker Compose1.1安装 Docker&#xff1a;1.2安装 Docker Compose&#xff1a; 2.创建目录结构3.编写docker-compose.yml4.ngin…

Java项目-基于springboot框架的财务管理系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

科研进展 | RSE:全波形高光谱激光雷达数据Rclonte系列处理算法一

《环境遥感》&#xff08;Remote Sensing of Environment&#xff0c;IF11.1&#xff09;近日发表一项来自中国科学院空天信息创新研究院王力、牛铮研究员团队的全波形高光谱激光雷达&#xff08;hyperspectral LiDAR&#xff0c;HSL&#xff09;数据处理算法研究&#xff0c;论…

计算机组成原理一句话

文章目录 计算机系统概述存储系统 计算机系统概述 指令和数据以同等地位存储在存储器中&#xff0c;形式上没有差别&#xff0c;但计算机应能区分他们。通过指令周期的不同阶段。 完整的计算机系统包括&#xff0c;1&#xff09;软件系统&#xff1a;程序、文档和数据&#xff…

DC系列靶机-DC6

一&#xff0c;环境的搭建 VM17 官网下载 kali 2023.4版 https://mirrors.tuna.tsinghua.edu.cn/kali-images/kali-2023.4/ 靶场文件 https://download.vulnhub.com/dc/DC-6.zip 二&#xff0c;攻略 首先进行主机发现&#xff1b; 接下来进行端口扫描&#xff1b; 开放了2…

初识git · 远程操作

目录 前言&#xff1a; 理解分布式版本控制系统 远程仓库 仓库操作 克隆仓库 推送和抓取 特殊文件 取别名 标签管理 前言&#xff1a; 在基本操作&#xff0c;分支管理这几个部分&#xff0c;我们都会在本地仓库操作了&#xff0c;但是目前还没有办法将自己的代码远程…

uniapp 实现input聚焦时选中内容(已封装)兼容微信小程序

老规矩先来看看效果噻&#xff01; 从上面的录屏中我们可以看出&#xff0c;要实现input自由选中内容的功能是可以实现的&#xff0c;原理其实很简单。 直接运行即可 <template><view><!-- <input class"psd"type"digit" :value"in…