lower_bound详解

lower_bound是C++标准模板库(STL)中的一个算法,用于在有序区间中查找第一个大于或等于给定值的元素的位置。这个函数非常有用,特别是当我们需要在有序数据集中进行二分查找时。下面是对lower_bound函数的详细讲解,包括其用法、原理、实现细节以及示例。

1. 函数原型
lower_bound函数的原型如下:

cpp
template <class ForwardIt, class T>  
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value);
first和last是迭代器,表示要搜索的范围。
value是要查找的值。
返回值是一个迭代器,指向在有序区间[first, last)中第一个大于或等于value的元素。如果找不到这样的元素,则返回last。
2. 用法示例
下面是一个简单的示例,展示如何使用lower_bound函数:

cpp
#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> v = {1, 2, 4, 4, 5, 6};  
    int value = 4;  
      
    auto it = std::lower_bound(v.begin(), v.end(), value);  
      
    if (it != v.end()) {  
        std::cout << "Found at index: " << std::distance(v.begin(), it) << std::endl;  
    } else {  
        std::cout << "Not found" << std::endl;  
    }  
      
    return 0;  
}
输出:

bash
Found at index: 2
在这个示例中,我们在有序向量v中查找值4。lower_bound函数返回一个迭代器,指向第一个大于或等于4的元素。我们使用std::distance函数来计算该元素在向量中的索引。

3. 原理与实现细节
lower_bound函数基于二分查找算法实现。二分查找是一种在有序数据集中查找特定元素的算法,其时间复杂度为O(log n)。lower_bound函数通过不断将搜索范围减半来找到目标值的位置。

具体来说,lower_bound函数的实现步骤如下:

初始化两个指针(或迭代器),一个指向区间的起始位置(first),另一个指向区间的结束位置(last)。
当first不等于last时,执行以下步骤:
计算中间位置mid = first + (last - first) / 2。注意这里使用(last - first) / 2而不是直接除以2,是为了避免在大数据集上发生整数溢出。
如果中间位置的值小于目标值(*mid < value),则将first更新为mid + 1,继续在右半部分搜索。
否则(中间位置的值大于或等于目标值),将last更新为mid,继续在左半部分或当前位置搜索。
返回first作为结果。此时,first指向的是第一个大于或等于目标值的元素的位置。如果找不到这样的元素,则返回last。
需要注意的是,由于二分查找算法的特性,lower_bound函数要求输入区间是有序的。如果输入区间无序,则结果不可预测。

4. 应用场景与扩展
lower_bound函数在多种场景下都非常有用,特别是当我们需要快速查找有序数据集中的特定元素时。以下是一些常见的应用场景:

在有序数组中查找元素:这是lower_bound函数最直接的应用场景。我们可以使用它来在有序数组中查找特定元素的位置。
在有序数组中查找插入位置:当我们需要在有序数组中插入一个新元素并保持数组有序时,可以使用lower_bound函数找到新元素的插入位置。这通常与std::vector的insert函数结合使用。
在有序集合中查找范围:我们可以使用lower_bound和upper_bound函数结合来查找有序集合中特定范围内的所有元素。这在处理统计数据或执行范围查询时非常有用。
自定义比较函数:除了使用默认的比较操作符外,我们还可以为lower_bound函数提供自定义的比较函数或Lambda表达式,以便根据特定的比较逻辑来查找元素。这在处理复杂数据类型或自定义排序规则时非常有用。
通过深入了解lower_bound函数的原理和实现细节,我们可以更好地利用这个强大的工具来解决各种实际问题。

lower_bound 是 C++ 标准库中的一个算法,它在一个有序序列中查找第一个不小于(即大于或等于)给定值的元素,并返回该元素的迭代器。如果序列中所有元素都小于给定值,则返回尾迭代器。

以下是使用 lower_bound 的五个案例:

案例 1:基本用法
cpp
#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> v = {1, 2, 4, 4, 5, 6, 7};  
    int target = 4;  
      
    auto it = std::lower_bound(v.begin(), v.end(), target);  
      
    if (it != v.end()) {  
        std::cout << "First element not less than " << target << " is at index " << (it - v.begin()) << std::endl;  
    } else {  
        std::cout << target << " not found in the vector" << std::endl;  
    }  
      
    return 0;  
}
输出:

bash
First element not less than 4 is at index 2
案例 2:在自定义对象上使用 lower_bound
cpp
#include <iostream>  
#include <vector>  
#include <algorithm>  
  
struct Person {  
    std::string name;  
    int age;  
      
    bool operator<(const Person& other) const {  
        return age < other.age;  
    }  
};  
  
int main() {  
    std::vector<Person> people = {{"Alice", 25}, {"Bob", 20}, {"Charlie", 30}};  
    int targetAge = 27;  
      
    auto it = std::lower_bound(people.begin(), people.end(), Person{"", targetAge},   
                               [](const Person& a, const Person& b) {  
                                   return a.age < b.age;  
                               });  
      
    if (it != people.end() && it->age == targetAge) {  
        std::cout << "Person with age " << targetAge << " found: " << it->name << std::endl;  
    } else {  
        std::cout << "No person with age " << targetAge << " found" << std::endl;  
    }  
      
    return 0;  
}
输出:

bash
No person with age 27 found
案例 3:在数组中使用 lower_bound
cpp
#include <iostream>  
#include <algorithm>  
  
int main() {  
    int arr[] = {1, 3, 5, 7, 9};  
    int n = sizeof(arr) / sizeof(arr[0]);  
    int target = 6;  
      
    int* result = std::lower_bound(arr, arr + n, target);  
      
    if (result != arr + n && *result == target) {  
        std::cout << "Element found at index " << (result - arr) << std::endl;  
    } else {  
        std::cout << "Element not found" << std::endl;  
    }  
      
    return 0;  
}
输出:

bash
Element not found
案例 4:处理重复元素
cpp
#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 3, 3, 4, 5};  
    int target = 3;  
      
    auto lower = std::lower_bound(v.begin(), v.end(), target);  
    auto upper = std::upper_bound(v.begin(), v.end(), target);  
      
    std::cout << "Range of " << target << " in the vector: ["   
              << (lower - v.begin()) << ", " << (upper - v.begin() - 1) << "]" << std::endl;  
      
    return 0;  
}
输出:

bash
Range of 3 in the vector: [2, 4]

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

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

相关文章

pyqt如何实现拖拽打开文件(通过windows的快捷方式打开文件)

桌面端的开发中如何通过windows的快捷方式打开文件&#xff0c;那么如何将需要打开的数据传递给qt程序呢&#xff1f; 研究了一下发现很简单 通过sys.argv可以轻松的实现传参 sys.argv import sys print(sys.argv)这个方法可以获取系统传递给程序的参数&#xff0c;默认是个列…

企业型多域名SSL证书

多域名SSL证书是目前市场上用的比较多的一种&#xff0c;主要解决多个不同规则的域名申请&#xff0c;但不适合主域名&#xff08;根域名&#xff09;相同的域名&#xff0c;因为这种域名直接申请通配符。 企业型其实就是OV类型或者EV类型&#xff0c;由于在CA/B产品名称规范中…

pi(2)

上一次我们说到了这个程序 #include <iostream> #include <cmath> #include <limits> int continuedFractionTerm(int n) { if (n 0) return 1; if (n % 2 0) { return 2 * n 1; } else { return 2 * n; } } std::pair<int, int> be…

jetson nano——安装archiconda

目录 1.archiconda3我在这提供了下载链接&#xff0c;点解下面链接即可1.看好文件所在位置&#xff0c;如果装错了&#xff0c;那么环境变量的路径自己进行相应的修改。2.添加环境变量 2.可能部分伙伴输入一些激活&#xff0c;啥的命令激活不了&#xff0c;那么输入下面这些代码…

react18加antd新手上路使用

第一次使用react和antd组件库&#xff0c;记录过程中实用的几个组件和使用方法&#xff1b; 项目中依赖版本 "react": "^18.2.0", "antd": "^5.3.0",Input关闭历史填充 <Input placeholder"请输入ID/名称" allowClear a…

深入浅出JVM(八)之类加载器

前文已经描述Java源文件经过前端编译器后变成字节码文件&#xff0c;字节码文件通过类加载器的类加载机制在Java虚拟机中生成Class对象 前文深入浅出JVM&#xff08;六&#xff09;之前端编译过程与语法糖原理重点描述过编译的过程 前文深入浅出JVM&#xff08;三&#xff09…

算法训练营day35(补),动态规划3

func max(a, b int) int { if a > b { return a } return b } //343. 整数拆分 //拆分的数尽量相等才能保证最大 func integerBreak(n int) int { dp : make([]int, n1) // 初始值&#xff0c;0,1没有意义&#xff0c;为零&#xff0c;2可以拆为1*11 dp[2] 1 for i :…

视频基础学习二——图像深度与格式(RGB与YUV)

文章目录 前言一、图像深度1.什么是图像深度2.图像深度的意义3.常见的图像深度8位16位24位32位 二、图像格式1.RGB格式2.RGB样式2.YUVYUV的来由YUV样式RGB和YUV之间的转换YUV的常见类型 总结 前言 本文的目的是为了梳理音视频基础相关的知识&#xff0c;有很多做流媒体、音视频…

高级语言期末2010级A卷

1.编写函数&#xff0c;按照如下公式计算圆周率π的值&#xff08;精确到1e-5&#xff09; #include <stdio.h>double pai() {double last0;double flag1;int n1;while(flag-last>1e-5) {lastflag;flag*1.0*(2*n)*(2*n)/((2*n-1)*(2*n1));n;}return 2*last; }int main…

基于SpringBoot的停车场管理系统

基于SpringBootVue的停车场管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台首页 停车位 个人中心 管理员界面 摘要 摘要&#xff1a;随着城市化进程的…

C#,计算几何,计算机图形学(Computer Graphics)洪水填充算法(Flood Fill Algorithm)与源代码

1 泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法(Flood Fill Algorithm) &#xff0c;又称洪水填充算法&#xff0c;是在很多图形绘制软件中常用的填充算法&#xff0c;最熟悉不过就是 windows 自带画图软件的油漆桶功能。 2 源程序 using System; using System.Collecti…

windows 虚拟机:CrossOver 24.0.0 for Mac破解版安装激活2024图文教程

CrossOver 24.0.0 for Mac是一款功能强大的虚拟机软件&#xff0c;允许在Mac系统上运行Windows应用程序而无需重新启动计算机。通过CrossOver&#xff0c;用户可以轻松地运行Windows软件和游戏&#xff0c;而无需购买Windows许可证或使用虚拟机。 CrossOver 24.0.0 for Mac通过…

MySQL-基本使用,数据类型,简单操作

1. 数据库概述 1.1 数据库(DatBase) 数据库&#xff0c;就是遵循一定数据格式的数据集合&#xff0c;可以认为他是对文件系统的改进。它解决了不同操作系统之间&#xff0c;数据格式的兼容性问题。也就是说&#xff0c;只要是同一个数据库的数据文件&#xff0c;即使从windows迁…

使用 kind 集群安装运行极狐GitLab Runner【下】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 上一篇内容中&#xff0c;我们已经利用 kind 创建好了一个本地…

GPT-SoVITS 快速声音克隆使用案例:webui、api接口

参考: https://github.com/RVC-Boss/GPT-SoVITS 环境: Python 3.10 PyTorch 2.1.2, CUDA 12.0 安装包: 1、使用: 1)下载项目 git clone https://github.com/RVC-Boss/GPT-SoVITS.git2)下载预训练模型 https://huggingface.co/lj1995/GPT-SoVITS 下载模型文件放到GPT…

C# (WebApi)整合 Swagger

SpringBoot-整合Swagger_jboot整合swagger-CSDN博客 C# webapi 也可以整合Swagger webapi运行其实有个自带的HELP页面 但是如果觉得UI不好看&#xff0c;且没办法显示方法注释等不方便的操作&#xff0c;我们也可以整合Swagger 一、使用NuGet控制台安装Swagger 在菜单中选择…

Pycharm服务器配置与内网穿透工具结合实现远程开发的解决方法

文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…

力扣随笔之颜色分类(中等75)

思路&#xff1a;定义两个指针划分left&#xff0c;right划分三个区域left左边是红色区域&#xff0c;right右边是蓝色区域&#xff0c;left和right之间是白色区域&#xff1b;定义一个遍历指针遍历整个数组&#xff0c;遇到红色与left所指位置数字交换&#xff0c;并将left自加…

Java IO缓冲流——字节缓冲流、字符缓冲流 IO流异常的处理(JDK7 JDK9)

缓冲流 缓冲流&#xff0c;也叫高效流&#xff0c;是对4个基本的FileXxx流的增强&#xff0c;所以也是4个流&#xff0c;按照数据类型分类&#xff1a; 字节缓冲流&#xff1a; BufferedInputStream&#xff0c;BufferedOutputStream字符缓冲流&#xff1a; BufferedReader&a…

暴雨服务器:科技创新构建高效、高质、可持续的新质生产力

1月31日&#xff0c;中共中央政治局就扎实推进高质量发展进行第十一次集体学习。会议指出&#xff0c;发展新质生产力是推动高质量发展的内在要求和重要着力点&#xff0c;并系统概括了新质生产力的总体定义、动力来源、基本内涵、核心标志以及发展思路。这其中&#xff0c;新质…