C++11标准模板(STL)- 算法(std::upper_bound)

news2025/1/31 11:10:14
定义于头文件 <algorithm>

算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为 [first, last) ,其中 last 指代要查询或修改的最后元素的后一个元素。

返回指向第一个大于给定值的元素的迭代器

std::upper_bound

template< class ForwardIt, class T >
ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value );

(1)(C++20 前)

template< class ForwardIt, class T >
constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value );

(C++20 起)

template< class ForwardIt, class T, class Compare >
ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value, Compare comp );

(2)(C++20 前)

template< class ForwardIt, class T, class Compare >
constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value, Compare comp );

(C++20 起)

返回指向范围 [first, last) 中首个大于 value 的元素的迭代器,或若找不到这种元素则返回 last

范围 [first, last) 必须已相对于表达式 !(value < element) 或 !comp(value, element) 划分,即所有令此表达式为 true 的元素必须前趋所有令此表达式为 false 的元素。完全排序的范围满足此判别标准。

第一版本用 operator< 比较元素,第二版本用给定的比较函数 comp

参数

first, last-要检验的元素范围
value-要与元素比较的值
comp-若第一参数小于(即先序于)第二个则返回 ​true 的二元谓词。

谓词函数的签名应等价于如下:

 bool pred(const Type1 &a, const Type2 &b);

虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 Type1Type2 的值,无关乎值类别(从而不允许 Type1 & ,亦不允许 Type1 ,除非 Type1 的移动等价于复制 (C++11 起))。
类型 Type1 必须使得 T 类型的对象能隐式转换到 Type1 。类型 Type2 必须使得 ForwardIt 类型的对象能在解引用后隐式转换到 Type2 。 ​

类型要求
- ForwardIt 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。
- Compare 必须满足二元谓词 (BinaryPredicate) 的要求。不要求满足 比较 (Compare) 。

返回值

指向首个大于 value 的元素的迭代器,或若找不到这种元素则为 last

复杂度

进行的比较次数与 firstlast 间的距离成对数(至多 log
2(last - first) + O(1) 次比较)。然而,对于非遗留随机访问迭代器 (LegacyRandomAccessIterator) ,迭代次自增次数为线性。

可能的实现

 版本一

template<class ForwardIt, class T>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value)
{
    ForwardIt it;
    typename std::iterator_traits<ForwardIt>::difference_type count, step;
    count = std::distance(first,last);
 
    while (count > 0) {
        it = first; 
        step = count / 2; 
        std::advance(it, step);
        if (!(value < *it)) {
            first = ++it;
            count -= step + 1;
        }
        else
            count = step;
    }
    return first;
}

版本二

template<class ForwardIt, class T, class Compare>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value, Compare comp)
{
    ForwardIt it;
    typename std::iterator_traits<ForwardIt>::difference_type count, step;
    count = std::distance(first,last);
 
    while (count > 0) {
        it = first; 
        step = count / 2;
        std::advance(it, step);
        if (!comp(value, *it)) {
            first = ++it;
            count -= step + 1;
        }
        else
            count = step;
    }
    return first;
}

调用示例

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <iterator>
#include <time.h>

using namespace std;

struct Cell
{
    int x;
    int y;

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

template<class ForwardIt, class T, class Compare>
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, Compare comp = {})
{
    // 注意:类型 T 和 Forward 解引用后的类型都必须可隐式转换为
    // 用于 Compare 的 Type1 和 Type2 。
    // 这严格于 lower_bound 要求(见上述)

    first = std::lower_bound(first, last, value, comp);
    return first != last && !comp(value, *first) ? first : last;
}

int main()
{
    srand((unsigned)time(NULL));;

    std::cout.setf(std::ios_base::boolalpha);

    auto func1 = []()
    {
        int n = std::rand() % 10 + 100;
        Cell cell{n, n};
        return cell;
    };

    vector<Cell> cells(8);
    std::generate(cells.begin(), cells.end(), func1);

    std::sort(cells.begin(), cells.end());
    std::cout << "cells :               ";
    std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl << std::endl;

    auto lower = std::lower_bound(cells.begin(), cells.end(), *(cells.begin() + 3));
    auto upper = std::upper_bound(cells.begin(), cells.end(), *(cells.begin() + 3));

    std::cout << "cells lower upper:    ";
    std::copy(lower, upper, std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl << std::endl;

    auto is_sortfa = [](const Cell & a, const Cell & b)
    {
        if (a.x == b.x)
        {
            return a.y < b.y;
        }
        return a.x < b.x;
    };

    auto is_sortfb = [](const Cell & a, const Cell & b)
    {
        if (a.x == b.x)
        {
            return a.y > b.y;
        }
        return a.x > b.x;
    };

    lower = std::lower_bound(cells.begin(), cells.end(), *(cells.begin() + 3), is_sortfa);
    upper = std::upper_bound(cells.begin(), cells.end(), *(cells.begin() + 3), is_sortfb);

    std::cout << "cells lower upper:    ";
    std::copy(lower, upper, std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl << std::endl;


    auto it = binary_find(cells.cbegin(), cells.cend(), *(cells.begin() + 3), is_sortfa);
    if (it != cells.cend())
    {
        std::cout << *it << " found at index " << std::distance(cells.cbegin(), it);
    }
    std::cout << std::endl ;

    return 0;
}

输出

 

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

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

相关文章

[附源码]Python计算机毕业设计钓鱼爱好者交流平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Java项目:电器商城系统(java+SSM+JSP+jQuery+javascript+Mysql)

源码获取&#xff1a;俺的博客首页 "资源" 里下载&#xff01; 项目介绍 本项目分为前后台&#xff0c;前台为普通用户登录&#xff0c;后台管理员登录&#xff1b; 管理员角色包含以下功能&#xff1a; 修改个人信息,员工信息管理,商品管理,图片管理,图表管理,用户…

解决vscode远程安装插件不了、安装太慢问题

一、问题描述 一直显示正在安装&#xff0c;几个小时也没动静&#xff0c;特别是那个c/c插件的安装。 二、解决方法 1、采用手动安装插件的方式 步骤&#xff1a; ①、先去这个网站找你要安装的插件&#xff0c;然后下载到本地电脑。 All categories Extensions - Visual Studi…

分汤000

题目链接 分汤 题目描述 注意 没有提供 0ml 的 汤A 和 100ml 的 汤B 这种操作如果汤的剩余量不足以完成某次操作&#xff0c;我们将尽可能分配 解答思路 由题意得&#xff0c;首先想到的是动态规划&#xff0c;关键是规律以及终止条件是怎样的由于分汤都是在25的倍数上进行…

内点法最优潮流matlab程序

内点法最优潮流matlab程序 一、概述最优潮流问题 1.最优潮流和基本潮流的比较潮流计算可以归结为针对一定的扰动变量p(负荷情况)&#xff0c;根据给定的控制变量u(如发电机的有功出力、无功出力或节点电压模值等)&#xff0c;求出相应的状态变量x(如节点电压模值及角度)&#x…

如何控制MySQL事务提交后,刷redo-log的策略?

既然涉及到事务提交&#xff0c;那么我们就是以InnoDB来说明的。 MySQL有一个参数&#xff0c;能够控制事务提交时&#xff0c;刷redo log的策略。该参数为&#xff1a;innodb_flush_log_at_trx_commit。 策略1,set global innodb_flush_log_at_trx_commit 0 该方式可以获得…

天然气潮流计算matlab程序

天然气潮流计算matlab程序 1 天然气潮流计算理论 由于天然气涉及到流体的运动方程&#xff0c;直接计算非常复杂&#xff0c;因此需要提前做出一些假设来简化计算&#xff0c;经过研究&#xff0c;适当的假设对结果影响很小&#xff0c;因此本文对天然气系统做出如下假设&#…

安装包UI美化之路-进度条的多种配置方法

安装包的进度条&#xff0c;你真正关心过么&#xff1f; 你知道如何配置出美观的进度条么&#xff1f;遇到特殊的进度条需求&#xff0c;你知道怎么实现么&#xff1f; 安装包的美化过程中&#xff0c;有一个细节比较重要&#xff0c;那就是进度条的呈现样式&#xff01; 呈现…

3、网关和BFF

一、网关和BFF的演进 v1 使用nginx负载均衡简单的微服务体系&#xff1b; v2 nginx直接暴露 v2.5无线BFF v3 集群BFF无线网关 v4无线网关、无线BFF根据业务集群化&#xff0c;废弃nginx集群 二、网关和反向代理 网关和反向代理的选择&#xff1a; 关于网关集群问题&#…

【自动化持续集成必备基础】pipeline常用功能

简介 ​pipeline是一套运行在jenkins上的工作流框架&#xff0c;可以实现复杂流程的编排和可视化运行 pipeline支持两种语法&#xff1a;Declarative Pipeline(声明式流水线)和Scripted Pipeline (脚本式流水线) 本文重点介绍主流的声明式流水线 创建流水线项目 在Jenkins中如果…

SpringBoot SpringBoot 原理篇 2 自定义starter 2.4 使用属性配置设置功能参数【1】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇2 自定义starter2.4 使用属性配置设置功能参数【1】2.4.1 直接开干2.4.2 小结…

linux驱动之调试技巧--- 应用程序远程gdb+vscode调试应用程序, 串口kgdboc调试.ko驱动程序

环境: Ubuntu: Ubuntu 22.04.1 开发板: imx6ull linux内核版本: Linux4.9.88 虚拟机: vmware15 交叉编译工具gcc版本: 4.9.4 (Linaro GCC 4.9-2017.01) arm-linux-gdb版本: gdb (Linaro_GDB-2017.01) 7.10.1.20160210 先决条件 开发板 虚拟机 PC 可互通网络 交叉编译环境已经搭…

哈希(Hash)

文章目录一、哈希是什么&#xff1f;二、哈希冲突三、开放定址法1.线性探测2.二次探测四、拉链法/哈希桶五、哈希的应用1.位图1.1 面试题1.2 位图概念1.3 位图的应用2.布隆过滤器2.1概念2.2布隆过滤器的查找2.3布隆过滤器的删除一、哈希是什么&#xff1f; Hash&#xff0c;一般…

语音识别系列︱利用达摩院ModelScope进行语音识别+标点修复(四)

终于有时间更新语音识别系列了&#xff0c;之前的几篇&#xff1a; 语音识别系列︱用python进行音频解析&#xff08;一&#xff09; 语音识别系列︱paddlehub的开源语音识别模型测试&#xff08;二&#xff09; 语音识别系列︱paddlespeech的开源语音识别模型测试&#xff08;…

1. JVM类加载机制

1. JVM类加载机制图解 下面我们来详细分析一下这个图解 1.1 其中loadClass()方法的调用的类加载的过程有如下几步 加载->验证->准备->解析->初始化->使用->卸载 加载&#xff1a;在硬盘上查找并通过IO读入字节码文件&#xff0c;当使用到这类的时候才会加…

[GYCTF2020]Ezsqli

先试一下万能密码 1 or 11# 发现有过滤&#xff0c;fuzz看一下过滤了什么 if&#xff0c;|&#xff0c;|| 没过滤&#xff0c;过滤了information_schema MySQL5.7新特性&#xff1a; 由于performance_schema过于复杂&#xff0c;所以mysql在5.7版本中新增了sys schemma&#x…

Docker实战之Redis主从集群搭建实战

实战 本实验将练习三主三从的Redis的docker集群快速搭建&#xff0c;实现集群的动态扩容和缩容&#xff0c;主从切换等常见实践项目。 拉取镜像 docker pull redis:6.0.8搭建主从 docker run -d --name redis-node-1 --net host --privilegedtrue -v /data/redis/share/red…

Allegro输出DXF文件操作指导

Allegro输出DXF文件操作指导 Allegro支持输出DXF文件,用于检查PCB的结构,具体操作如下 首先在PCB上打开需要的输出的层面,需要哪层开哪层,如下图所示 点击file-export 弹出一个对话框,输入文件名,格式选择Reversion14 ,单位选择mm,精度选择4 然后点击Edit 会出现一…

视频播放

QMediaPlayer不仅可以播放音频&#xff0c;还可以播放视频&#xff0c;不过要在屏幕上显示的话需要使用QVideoWidget和QGraphicsVideoItrm或自定义的类。QMovie 播放GIF文件QVideoWidget和QGraphicsVideoItrm都属于QMulimedia Widgets模块QVideoWidget 继承自QWiaget&#xff0…

Android Studio下载安装

一、下载 二、安装步骤 点击下载的安装包&#xff0c;选择地址的时候可以自定义&#xff0c;其他按照默认配置即可。 启动应用&#xff0c;开始配置 选择安装类型为标准安装&#xff1a; 选择主题 确认配置 同意协议 开始下载相关组件&#xff1a; 下载完成