C++ 手写实现类似lower_bound和upper_bound的二分功能

目录

  • lower_bound和upper_bound介绍
  • 手动实现类似的二分效果
    • lower_bound
    • upper_bound
    • 另一种常见的二分形式
  • 对lower_bound函数使用lamda函数

lower_bound和upper_bound介绍

lower_bound函数的作用是查找范围内第一个大于等于目标元素的元素迭代器/指针

数组的简单使用:

int num[5]={1,3,5,7,9};
int *pos=lower_bound(num,num+5,key);
int num[5]={1,3,5,7,9}
int pos=lower_bound(num,num+5,key)-num;

vector容器的简单使用:

vector<int> ve{1,3,5,7,9}
vector<int>::iterator pos=lower_bound(ve.begin(),ve.end(),key);
vector<int> ve{1,3,5,7,9}
auto pos=lower_bound(ve.begin(),ve.end(),key)-ve.begin();

upper_bound的作用是查找范围内第一个大于目标元素的元素迭代器/指针
使用方法和lower_bound相同

手动实现类似的二分效果

lower_bound函数是查找范围内第一个大于等于
upper_bound函数是查找范围内第一个大于
并且如果范围内没有符合条件的值,就返回范围内最后一个元素的下一个迭代器/指针

接下来将写两个简单的二分函数,实现二分查找目标范围内第一个大于等于/大于的值,如果找不到范围内最后一个元素的下一个元素的位置.

lower_bound

#include<bits/stdc++.h>
using namespace std;

int lower_bound(int a[],int left,int right,int key)
{
	while(left<=right)
	{
		int mid=(left+right)>>1;
		
		if(a[mid]>=key)
		{
			right=mid-1;
		}
		else
		left=mid+1; 
	}
	
	return left;
 } 
int main()
{
    int a[5]={1,3,5,7,9};
    
    cout<< lower_bound(a,0,4,6) <<endl;
    cout<< lower_bound(a,0,4,100)<<endl;
}

upper_bound

#include<bits/stdc++.h>
using namespace std;

int upper_bound(int a[],int left,int right,int key)
{
	while(left<=right)
	{
		int mid=(left+right)>>1;
		
		if(a[mid]>key)
		{
			right=mid-1;
		}
		else
		left=mid+1; 
	}
	
	return left;
 } 
int main()
{
    int a[5]={1,3,5,7,9};
    
    cout<< upper_bound(a,0,4,6) <<endl;
    cout<< upper_bound(a,0,4,100)<<endl;
}

另一种常见的二分形式

这样写也能实现二分的功能,但是没办法在找不到的情况下返回正确的值.

#include<bits/stdc++.h>
using namespace std;

int lower_bound(int a[],int left,int right,int key)
{
	while(left<right)
	{
		int mid=(left+right)>>1;
		
		cout<<left<<" "<<right<<" "<<mid<<endl;
		
		if(a[mid]>=key)
		{
			right=mid;
		}
		else
		left=mid+1; 
	}
	
	return left;
 } 
int main()
{
    int a[5]={1,3,5,7,9};
    
    cout<< lower_bound(a,0,4,7) <<endl;
}

对lower_bound函数使用lamda函数

lower_bound函数是实际是有四个参数的
在这里插入图片描述

最后一个参数是比较规则,我们可以在第四个参数的位置,放上函数指针自定义排序规则.

也可以放入lamda表达式
仔细看,lower_bound函数中的_Val也就是上文说的Key值,它会在运行过程中将自己的值传递给比较函数中的第二个参数.

代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

vector<int> ve{ -1,3,-5,-6,7 };
int main()
{
    std::sort(ve.begin(), ve.end());

    int pos = lower_bound(ve.begin(), ve.end(), 3, [](int a, int b) {

        cout << a << " " << b << endl;

        return a < b;
        }) - ve.begin();

    cout << pos << endl;
}

我们可以打印a和b来观察二分过程中lamda表达式中参数的变化.发现参数b的值始终=_Val的值是不变的.

我们可以自定义二分的规则,但是前提是,二分的数组必须是有序的(升序或者降序)都行,并且比较的规则也需要是有单调性的.

我们也可以利用lamda函数对一个降序的数组,求数组中第一个小于等于目标元素的元素位置

代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> ve{ -1,3,-5,-6,7 };
int main()
{
    std::sort(ve.begin(), ve.end(),[](int a,int b)
	{
		return a>b;
	});
	// 7 3 -1 -5 -6
    
	int pos=lower_bound(ve.begin(),ve.end(),-7,[](int a,int b){
		
		return a>b;
	})-ve.begin();
	
	cout<<pos<<endl;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode 与 C++

序 具体流程的话&#xff0c;官方文档里都有的&#xff1a;C programming with Visual Studio Code 浏览器下载一个mingw64&#xff0c;解压&#xff0c;配置环境变量vscode里安装c相关的插件没了 第一步只看文字&#xff0c;可能有点抽象&#xff0c;相关视频&#xff1a; …

科技云报道:AI+云计算共生共长,能否解锁下一个高增长空间?

科技云报道原创。 在过去近一年的时间里&#xff0c;AI大模型从最初的框架构建&#xff0c;逐步走到落地阶段。 然而&#xff0c;随着AI大模型深入到千行百业中&#xff0c;市场开始意识到通用大模型虽然功能强大&#xff0c;但似乎并不能完全满足不同企业的个性化需求。 大…

Three.js后处理后物体表面出现条纹

初始化 WebGLRenderer 时简单启用 logarithmicDepthBuffer: true 解决了问题。 根据文档&#xff0c;启用可能会导致性能下降&#xff0c;因此请根据您的性能预算考虑使用它。 缩小相机的near和far 后处理对于深度精度非常敏感。大视锥体很快就会使此类 AO 通道变得无法使用 th…

因果推断(六)基于微软框架dowhy的因果推断

因果推断&#xff08;六&#xff09;基于微软框架dowhy的因果推断 DoWhy 基于因果推断的两大框架构建&#xff1a;「图模型」与「潜在结果模型」。具体来说&#xff0c;其使用基于图的准则与 do-积分来对假设进行建模并识别出非参数化的因果效应&#xff1b;而在估计阶段则主要…

合宙Air724UG LuatOS-Air LVGL API控件--容器 (Container)

容器 (Container) 容器是 lvgl 相当重要的一个控件了&#xff0c;可以设置布局&#xff0c;容器的大小也会自动进行调整&#xff0c;利用容器可以创建出自适应成都很高的界面布局。 代码示例 – 创建容器 cont lvgl.cont_create(lvgl.scr_act(), nil) lvgl.obj_set_auto_re…

java之SpringBoot基础、前后端项目、MyBatisPlus、MySQL、vue、elementUi

文章目录 前言JC-1.快速上手SpringBootJC-1-1.SpringBoot入门程序制作&#xff08;一&#xff09;JC-1-2.SpringBoot入门程序制作&#xff08;二&#xff09;JC-1-3.SpringBoot入门程序制作&#xff08;三&#xff09;JC-1-4.SpringBoot入门程序制作&#xff08;四&#xff09;…

C语言练习7(巩固提升)

C语言练习7 编程题 前言 “芳林新叶催陈叶&#xff0c;流水前波让后波。”改革开放40年来&#xff0c;我们以敢闯敢干的勇气和自我革新的担当&#xff0c;闯出了一条新路、好路&#xff0c;实现了从“赶上时代”到“引领时代”的伟大跨越。今天&#xff0c;我们要不忘初心、牢记…

NV21、NV12、YV12、RGB565、YUV等颜色编码格式区别和接口设计探讨

NV21、NV12、YV12、RGB565、YUV扫盲 NV21、NV12、YV12、RGB565、YUV分别是不同的颜色编码格式&#xff0c;这些颜色编码格式各有特点&#xff0c;适用于不同的应用场景。选择合适的颜色编码格式取决于具体的需求和环境&#xff1a; NV21&#xff1a;NV21是一种用于Android系统…

JVM的故事——类文件结构

类文件结构 文章目录 类文件结构一、概述二、无关性基石三、Class类文件的结构 一、概述 计算机是只认由0、1组成的二进制码的&#xff0c;不过随着发展&#xff0c;我们编写的程序可以被编译成与指令集无关、平台中立的一种格式。 二、无关性基石 对于不同平台和不同平台的…

最小生成树 -prim算法

一般无向图建图稠密图-prim算法稀疏图-kruskal算法 prim : 加点法 1.先随机选一个点&#xff0c;加入集合 &#xff0c;之后寻找最短的距离的点加入集合&#xff0c;行程最小生成树。 2.注意最小生成树是不能有回路的&#xff0c; 所以可以把回路设置成最大值&#xff0c;即假装…

【python爬虫】8.温故而知新

文章目录 前言回顾前路代码实现体验代码功能拆解获取数据解析提取数据存储数据 程序实现与总结 前言 Hello又见面了&#xff01;上一关我们学习了爬虫数据的存储&#xff0c;并成功将QQ音乐周杰伦歌曲信息的数据存储进了csv文件和excel文件。 学到这里&#xff0c;说明你已经…

k8s etcd 简介

Etcd是CoreOS基于Raft协议开发的分布式key-value存储&#xff0c;可用于服务发现、共享配置以及一致性保障&#xff08;如数据库选主、分布式锁等&#xff09;。 如&#xff0c;Etcd也可以作为微服务的注册中心&#xff0c;比如SpringCloud也基于ETCD实现了注册中心功能&#…

Jmete+Grafana+Prometheus+Influxdb+Nginx+Docker架构搭建压测体系/监控体系/实时压测数据展示平台+遇到问题总结

背景 需要大批量压测时&#xff0c;单机发出的压力能力有限&#xff0c;需要多台jmeter来同时进行压测&#xff1b;发压机资源不够&#xff0c;被压测系统没到瓶颈之前&#xff0c;发压机难免先发生资源不足的情形&#xff1b;反复压测时候也需要在不同机器中启动压测脚本&…

OpenCV c++ 使用imshow显示灰色窗口

OpenCV使用imshow显示灰色窗口 原因是使用了system(‘pause’);函数&#xff0c;只需要将该函数去掉&#xff0c;使用opencv中的对应函数 waitKey(0) 即可实现同样效果。 system(“pause”); 改为&#xff1a; cv::waitKey(0); 显示效果&#xff1a;

金融客户敏感信息的“精细化管控”新范式

目 录 01 客户信息保护三箭齐发&#xff0c;金融IT亟需把握四个原则‍ 02 制度制约阻碍信息保护的精细化管控 ‍‍‍‍‍‍‍ 03 敏感信息精细化管控范式的6个关键设计 04 分阶段实施&#xff0c;形成敏感信息管控的长效运营的机制 05 未来&#xff0c;新挑战与新机遇并存 …

2023蓝帽杯初赛ctf部分题目

Web LovePHP 打开网站环境&#xff0c;发现显示出源码 来可以看到php版本是7.4.33 简单分析了下&#xff0c;主要是道反序列化的题其中发现get传入的参数里有_号是非法字符&#xff0c;如果直接传值传入my_secret.flag&#xff0c;会被php处理掉 绕过 _ 的方法 对于__可以…

vue自定义事件 div 拖拽方法缩小

在main.js 引用 // 引入拖动js import dragMove from "./utils/dragMove.js" 创建 drawmove.js export default (app) > {app.directive(dragMove, (el, binding) > {const DragVindow el.querySelector(binding.value.DragVindow)// 按下鼠标处理事件con…

【java中的Set集合】HashSet、LinkedHashSet、TreeSet(最通俗易懂版!!)

目录 一、HashSet集合 1.HashSet集合的特点 2.HashSet常用方法 二、LinkedHashSet集合 LinkedHashSet集合的特点 三、TreeSet集合 1.TreeSet集合的特点 2.TreeSet的基本使用 四、HashSet、LinkedHashSet、TreeSet的使用场景 五、list和set集合的区别 一、HashSet集合 …

分布式任务调度框架

分布式任务调度框架 学习为主 文章目录 分布式任务调度框架一、概念二、架构图三、任务调度的流程定时触发任务是如何实现的&#xff1f;&#xff1a;使用时间轮实现定时执行任务逻辑:3.1 对到达now时间后的任务&#xff08;超出now 5秒外)3.2 对到达now时间后的任务&#xff0…

苹果为 Vision Pro 头显申请游戏手柄专利

苹果Vision Pro 推出后&#xff0c;美国专利局公布了两项苹果公司申请的游戏手柄专利&#xff0c;其中一项的专利图如下图所示。据 PatentlyApple 报道&#xff0c;虽然申请专利并不能保证苹果公司会推出游戏手柄&#xff0c;但是苹果公司同时也为游戏手柄申请了商标&#xff0…