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

news2024/11/23 5:39:56
定义于头文件 <algorithm>

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

归并两个已排序的范围

std::merge
template< class InputIt1, class InputIt2, class OutputIt >

OutputIt merge( InputIt1 first1, InputIt1 last1,
                InputIt2 first2, InputIt2 last2,

                OutputIt d_first );
(1)(C++20 前)
template< class InputIt1, class InputIt2, class OutputIt >

constexpr OutputIt merge( InputIt1 first1, InputIt1 last1,
                          InputIt2 first2, InputIt2 last2,

                          OutputIt d_first );
(C++20 起)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class ForwardIt3 >

ForwardIt3 merge( ExecutionPolicy&& policy,
                  ForwardIt1 first1, ForwardIt1 last1,
                  ForwardIt2 first2, ForwardIt2 last2,

                  ForwardIt3 d_first );
(2)(C++17 起)
template< class InputIt1, class InputIt2, class OutputIt, class Compare>

OutputIt merge( InputIt1 first1, InputIt1 last1,
                InputIt2 first2, InputIt2 last2,

                OutputIt d_first, Compare comp );
(3)(C++20 前)
template< class InputIt1, class InputIt2, class OutputIt, class Compare>

constexpr OutputIt merge( InputIt1 first1, InputIt1 last1,
                          InputIt2 first2, InputIt2 last2,

                          OutputIt d_first, Compare comp );
(C++20 起)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class ForwardIt3, class Compare>

ForwardIt3 merge( ExecutionPolicy&& policy,
                  ForwardIt1 first1, ForwardIt1 last1,
                  ForwardIt2 first2, ForwardIt2 last2,

                  ForwardIt3 d_first, Compare comp );
(4)(C++17 起)

归并二个已排序范围 [first1, last1)[first2, last2) 到始于 d_first 的一个已排序范围中。

1) 用 operator< 比较元素。

3) 用给定的二元比较函数 comp 比较元素。

2,4) 同 (1,3) ,但按照 policy 执行。这些重载仅若 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> 为 true 才参与重载决议。

对于元范围中的等价元素,来自第一范围的元素(保持其原顺序)先于来自第二范围的元素(保持其原顺序)。

若目标范围与输入范围之一重叠,则行为未定义(输入范围可相互重叠)。

参数

first1, last1-要归并的元素的第一范围
first2, last2-要归并到元素的第二范围
d_first-目标范围的起始
policy-所用的执行策略。细节见执行策略。
comp-比较函数对象(即满足比较 (Compare) 概念的对象),若第一参数小于(即序于)第二参数则返回 ​true 。

比较函数的签名应等价于如下:

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

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

类型要求
- InputIt1, InputIt2 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。
- ForwardIt1, ForwardIt2, ForwardIt3 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。
- OutputIt 必须满足遗留输出迭代器 (LegacyOutputIterator) 的要求。

返回值

指向最后复制元素后一元素的迭代器。

复杂度

1,3) 至多 std::distance(first1, last1) + std::distance(first2, last2) - 1 次比较。

2,4) O(std::distance(first1, last1) + std::distance(first2, last2)) 。

异常

拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

  • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 为标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
  • 若算法无法分配内存,则抛出 std::bad_alloc 。

注意

此算法进行类似 std::set_union 所做的任务。都消耗二个已排序输入范围,并产生拥有来自两个输入的元素的输出。此二算法的区别在于处理来自二个输入的比较等价(见可小于比较 (LessThanComparable) 上的注意)的值。若任何等价的值在第一范围出现 n 次,在第二范围出现 m 次,则 std::merge 会输出所有 n+m 次出现,而 std::set_union 将只输出 std::max(n, m) 次。故 std::merge 准确输出 std::distance(first1, last1) + std::distance(first2, last2) 个值,而 std::set_union 可能产生得更少。

可能的实现

版本一

template<class InputIt1, class InputIt2, class OutputIt>
OutputIt merge(InputIt1 first1, InputIt1 last1,
               InputIt2 first2, InputIt2 last2,
               OutputIt d_first)
{
    for (; first1 != last1; ++d_first) {
        if (first2 == last2) {
            return std::copy(first1, last1, d_first);
        }
        if (*first2 < *first1) {
            *d_first = *first2;
            ++first2;
        } else {
            *d_first = *first1;
            ++first1;
        }
    }
    return std::copy(first2, last2, d_first);
}

 版本二

template<class InputIt1, class InputIt2,
         class OutputIt, class Compare>
OutputIt merge(InputIt1 first1, InputIt1 last1,
               InputIt2 first2, InputIt2 last2,
               OutputIt d_first, Compare comp)
{
    for (; first1 != last1; ++d_first) {
        if (first2 == last2) {
            return std::copy(first1, last1, d_first);
        }
        if (comp(*first2, *first1)) {
            *d_first = *first2;
            ++first2;
        } else {
            *d_first = *first1;
            ++first1;
        }
    }
    return std::copy(first2, last2, d_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;
}

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> cells1(5);
    std::generate(cells1.begin(), cells1.end(), func1);
    std::stable_sort(cells1.begin(), cells1.end());

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

    vector<Cell> cells2(5);
    std::generate(cells2.begin(), cells2.end(), func1);
    std::stable_sort(cells2.begin(), cells2.end());

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

    vector<Cell> cells3(cells1.size() + cells2.size());
    std::merge(cells1.begin(), cells1.end(), cells2.begin(), cells2.end(), cells3.begin());

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

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

    vector<Cell> cells4(5);
    std::generate(cells4.begin(), cells4.end(), func1);
    std::stable_sort(cells4.begin(), cells4.end(), is_sortf);

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

    vector<Cell> cells5(5);
    std::generate(cells5.begin(), cells5.end(), func1);
    std::stable_sort(cells5.begin(), cells5.end(), is_sortf);

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

    vector<Cell> cells6;
    std::merge(cells4.begin(), cells4.end(), cells5.begin(), cells5.end(), std::back_inserter(cells6), is_sortf);

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

    return 0;
}

输出

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

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

相关文章

关于Mysql使用left join写查询语句执行很慢的问题解决

目录 &#xff08;一&#xff09;前言 &#xff08;二&#xff09;正文 1. 表结构/索引展示 &#xff08;1&#xff09;表结构 &#xff08;2&#xff09;各表索引情况 2. 存在性能问题的SQL语句 3. 解决思路 &#xff08;1&#xff09;执行计划思路调优 &#xff08;…

数字图像处理(入门篇)二 颜色空间

在对图像进行处理时&#xff0c;前提图像必须是以数据的形式来描述的&#xff0c;而颜色空间就是用数据来表征图像颜色的一种方法。颜色信息由三个独立的分量来综合表示&#xff0c;这三个独立的分量构成了一个三维的坐标空间&#xff0c;每种颜色信息都在该空间中被唯一地表示…

Java-泛型实验

1.定义一个学生类Student&#xff0c;具有年龄age和姓名name两个属性&#xff0c;并通过实现Comparable接口提供比较规则&#xff08;返回两个学生的年龄差&#xff09;&#xff0c; 定义测试类Test&#xff0c;在测试类中定义测试方法Comparable getMax(Comparable c1, Compar…

基于springboot农机电招平台设计与实现的源码+文档

摘要 随着农机电招行业的不断发展&#xff0c;农机电招在现实生活中的使用和普及&#xff0c;农机电招行业成为近年内出现的一个新行业&#xff0c;并且能够成为大群众广为认可和接受的行为和选择。设计农机电招平台的目的就是借助计算机让复杂的销售操作变简单&#xff0c;变高…

Kubernetes资源调度之节点亲和

Kubernetes资源调度之节点亲和 Pod节点选择器 nodeSelector指定的标签选择器过滤符合条件的节点作为可用目标节点&#xff0c;最终选择则基于打分机制完成。因此&#xff0c;后者也称为节点选择器。用户事先为特定部分的Node资源对象设定好标签&#xff0c;而后即可配置Pod通过…

YOLO X 改进详解

YOLO X 主要改进&#xff1a; Anchor-Free: FCOSDecoupled detection headAdvanced label assigning strategy Network structure improvement Decoupled detection head 对比于YOLO V5, YOLO X 在detection head上有了改进。YOLO V5中&#xff0c;检测头是通过卷积同时预…

ROS2--概述

ROS2概述1 ROS2对比ROS12 ROS2 通信3 核心概念4 ros2 安装5 话题、服务、动作6 参数参考1 ROS2对比ROS1 多机器人系统&#xff1a;未来机器人一定不会是独立的个体&#xff0c;机器人和机器人之间也需要通信和协作&#xff0c;ROS2为多机器人系统的应用提供了标准方法和通信机…

时间序列:时间序列模型---自回归过程(AutoRegressive Process)

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 这次我们构造一个由无限的白噪声实现&#xff08;white noise realization) 组成的时间序列&#xff0c;即。这个由无限数目的项组成的值却是一个有限的值&#xff0c;比如时刻的值为&#xff0c; 而…

基于PHP+MySQL校园餐饮配送系统的设计与实现

随着我国国民经济的稳步发展,我国的大学生也越来越多,但是大部分学生都是没有时间和环境去自己做饭的,有很多也不会做,而很多食堂的菜品有难以下咽,所以很多人就采取了订餐的方式来进行购买美食,但是现在很多网站都是只能进行点餐,而没有智能推荐功能,本系统在原来的外卖基础上…

【Linux】文件系统

目录&#x1f308;前言&#x1f337;1、磁盘的组成&#x1f361;1.1、磁盘的物理结构&#x1f362;1.2、磁盘的存储结构&#x1f363;1.3、磁盘的逻辑结构&#x1f338;2、文件系统&#x1f364;2.1、文件系统的结构&#x1f365;2.2、inode如何与数据块建立联系&#x1f366;2…

2021年全国研究生数学建模竞赛华为杯C题帕金森病的脑深部电刺激治疗建模研究求解全过程文档及程序

2021年全国研究生数学建模竞赛华为杯 C题 帕金森病的脑深部电刺激治疗建模研究 原题再现&#xff1a; 一、背景介绍   帕金森病是一种常见的神经退行性疾病&#xff0c;临床表现的特征是静止性震颤&#xff0c;肌强直&#xff0c;运动迟缓&#xff0c;姿势步态障碍等运动症…

R语言生存分析可视化分析

生存分析指的是一系列用来探究所感兴趣的事件的发生的时间的统计方法。 生存分析被用于各种领域&#xff0c;例如&#xff1a; 癌症研究为患者生存时间分析&#xff0c; “事件历史分析”的社会学 在工程的“故障时间分析”。 在癌症研究中&#xff0c;典型的研究问题如下…

Java中如何处理时间--Date类

文章目录0 写在前面1 介绍Date类2 构造方法举例2.1 Date()2.2 Date(long date)3 Date类中常用方法4 写在最后0 写在前面 在实际业务中&#xff0c;总会碰到关于时间的问题&#xff0c;例如收集当年的第一季度的数据。第一季度也就是当年的一月一日到三月三十一日。如何处理时间…

使用markdown画流程图、时序图等

概述 能表示的图类型还有很多&#xff0c;比如&#xff1a; sequenceDiagram时序图 classDiagram类图 stateDiagram:状态图 erDiagram&#xff1a;ER图 gantt&#xff1a; 甘特图 pie&#xff1a;饼图 requirementDiagram: 需求图 流程图 流程图代码以「graph 《布局…

【毕业设计】12-基于单片机的电子体温计(原理图工程+源码工程+仿真工程+答辩论文)

【毕业设计】12-基于单片机的电子体温计&#xff08;原理图工程源码工程仿真工程答辩论文&#xff09; 文章目录【毕业设计】12-基于单片机的电子体温计&#xff08;原理图工程源码工程仿真工程答辩论文&#xff09;任务书设计说明书摘要设计框架架构设计说明书及设计文件源码展…

Efficient Large-Scale Language Model Training on GPU ClustersUsing Megatron-LM

Efficient Large-Scale Language Model Training on GPU ClustersUsing Megatron-LM 1 INTRODUCTION 在这篇文章中展示了 如何将 tensor &#xff0c;pipeline&#xff0c; data 并行组合&#xff0c;扩展到数千个GPU上。 提出了一个新的交错流水线调度&#xff0c;可以提升1…

卷积神经网络的工程技巧总结

参考 卷积神经网络的工程技巧(tricks) - 云社区 - 腾讯云 要成功地使用深度学习算法&#xff0c;仅仅知道存在哪些算法和解释它们为何有效的原理是不够的。一个优秀的机器学习实践者还需知道如何针对具体应用挑选一个合适的算法以及如何监控&#xff0c;并根据实验反馈改进机器…

基于 Hive 的 Flutter 文档类型存储

基于 Hive 的 Flutter 文档类型存储 原文 https://medium.com/gytworkz/document-type-storage-in-flutter-using-hive-a18ea9659d84 前言 长久以来&#xff0c;我们一直使用共享首选项以键对格式在本地存储中存储数据&#xff0c;或者使用 SQLite 在 SQL 数据库中存储数据。 存…