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

news2024/9/25 11:16:29
定义于头文件 <algorithm>

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

计算两个集合的差集

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

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

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

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

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

ForwardIt3 set_difference( 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 set_difference( 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 set_difference( 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 set_difference( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1,
                           ForwardIt2 first2, ForwardIt2 last2,

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

复制来自已排序范围 [first1, last1) 并且不在已排序范围 [first2, last2) 中找到的元素到始于 d_first 的范围。

结果范围亦已排序。单独对待等价元素,即若某元素在 [first1, last1) 中找到 n 次而在 [first2, last2) 中找到 m 次,则它将被准确复制 std::max(m-n, 0) 次到 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-要搜索的元素范围
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) 的要求。
- OutputIt 必须满足遗留输出迭代器 (LegacyOutputIterator) 的要求。
- ForwardIt1, ForwardIt2, ForwardIt3 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。

返回值

构造的范围的尾后迭代器。

复杂度

至多 2·(N1+N2-1) 次比较,其中 N1 = std::distance(first1, last1) 而 N2 = std::distance(first2, last2) 。

异常

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

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

可能的实现

 版本一

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

版本二

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

    // 初始化cells1
    vector<Cell> cells1(8);
    std::generate(cells1.begin(), cells1.end(), func1);

    // 排序cells1
    std::stable_sort(cells1.begin(), cells1.end());

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

    // 初始化cells2
    vector<Cell> cells2(5);
    std::generate(cells2.begin(), cells2.end(), func1);
    // 排序cells2
    std::stable_sort(cells2.begin(), cells2.end());

    // 打印cells2
    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());
    using CIt = std::vector<Cell>::iterator;
    CIt last = std::set_difference(cells1.begin(), cells1.end(), cells2.begin(), cells2.end(), cells3.begin());

    // 打印cells3
    std::cout << "cells 3 :     ";
    std::copy(cells3.begin(), last, 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;
    };

    // 初始化cells4
    vector<Cell> cells4(8);
    std::generate(cells4.begin(), cells4.end(), func1);

    // 排序cells4
    std::stable_sort(cells4.begin(), cells4.end(), is_sortf);

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

    // 初始化cells5
    vector<Cell> cells5(5);
    std::generate(cells5.begin(), cells5.end(), func1);

    // 排序cells5
    std::stable_sort(cells5.begin(), cells5.end(), is_sortf);

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

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

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

    return 0;
}

输出

 

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

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

相关文章

Maven的简单介绍

Maven 构件 <packaging> : pom、jar、ear、war以及maven-plugin,构建Maven之后所生成的文件类型&#xff0c;Pom本身不产生构件&#xff0c;用来作为依赖库。 pom类型常用于微服务中作为父Pom,通过 可以将子模块包含进来&#xff0c;共享父Pom的依赖&#xff0c; GAV坐标…

【数据库与事务系列】多数据源切换

分库分表 不光是管理多个数据源&#xff0c;是对sql的优化、改写、归并等一系列操作的解决方案。关注的是sql语句。以shardingSphere为例&#xff0c;虽然也支持跟sql无关的hint策略提供路由功能&#xff0c;但是在sql改写以及归并过程中&#xff0c;依旧对sql有限制。 多数据…

页面转变为灰色,如此简单

页面转变为灰色 网站变灰色 html标签 一、通过浏览器操作 在网页端按下 F12&#xff0c;打开开发者模式&#xff0c;用元素选择器定位到 HTML 标签上&#xff0c;在「样式」的面板中往下翻&#xff0c;就可以看到这样一段代码。 在html标签添加filter: grayscale(100%); 效…

LAS、CTC、RNN-T、NT、MoChA

LAS LAS是一个做语音识别的经典seq2seq模型&#xff0c;主要分为三个部分Listen、Attention、Spell Listen Listen部分就是一个encoder。 输入声学特征向量&#xff0c;提取信息、消除噪声&#xff0c;输出向量。 encoder可以是RNN 也可以是CNN。比较常见的是先用CNN&…

多元宇宙算法求解电力系统多目标优化问题(Matlab实现)【电气期刊论文复现与算例创新】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f4dd;目前更新&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;电力系统相关知识&#xff0c;期刊论文&…

Shiro-SpringBoot (一)

前不久负责项目中刚好也使用了Shiro做权限控制&#xff0c;趁着空闲期想把之前做的整理一下。在日常项目开发中&#xff0c;权限认证是不可少的模块。比较常用的有Spring Security&#xff0c;或是轻量级的Apache Shiro。相对来说Shiro提供了认证、授权、加密、会话管理、与Web…

华为机试 - 羊、狼、农夫过河

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 羊、狼、农夫都在岸边&#xff0c;当羊的数量小于狼的数量时&#xff0c;狼会攻击羊&#xff0c;农夫则会损失羊。农夫有一艘容量固定的船&#xff0c;能够承载固定数量的动物。 要求求出不损失羊情况…

体验Vue3的SSR框架 - Nuxt3

SSR 与 Nuxt SSR 是 Server-Side Rendering&#xff0c;即服务端渲染的英文缩写。 Vue.js 是一个用于构建客户端应用的框架。默认情况下&#xff0c;Vue 组件的职责是在浏览器中生成和操作 DOM。在客户端是单页应用 (SPA) 。 也可以将 vue 程序在服务端渲染&#xff0c;渲染…

【GD-1开发板】CH340驱动安装方法

CH340驱动安装方法正常情况异常情况CH340驱动安装步骤现在国产ARM替代STM32的arm芯片运动正如火如荼进行中&#xff0c;我也录制了一套完整的”ARM嵌入式开发入门教程“&#xff0c;并配套了一个GD32F103C8T6的开发板。 但有小伙伴拿到板子后&#xff0c;说下载程序的时候&…

实验七:定时/计数器8253、8254

目录 例实验目的实验内容报告要求例 已知8253的两个计数器CLK0=1MHZ,CLK1=1KHZ,现系统要求8253的OUT1产生0.1s的定时方波信号。 (1):应如何实现? (2):说明两个计数器的工作方式并计算计数初值 (3):编写初始化程序(8253的端口地址80H-83H,均采用二进制计数) C…

详解torch.nn.functional.grid_sample函数(通俗易懂):可实现对特征图的水平/垂直翻转

一、函数介绍 Pytorch中grid_sample函数的接口声明如下&#xff0c;具体网址可以点这里 torch.nn.functional.grid_sample(input, grid, mode‘bilinear’, padding_mode‘zeros’, align_cornersNone) 为了简单起见&#xff0c;以下讨论都是基于如下参数进行实验及讲解的&…

BSN开放联盟链“中移链”浏览器2.0正式发布!

由中国移动信息技术中心自主研发的中移链EOS区块链浏览器2.0版本&#xff0c;已在区块链服务网络&#xff08;BSN&#xff09;官网和BSN-DDC网络官网正式发布。 中移链浏览器2.0 无论是从政策导向还是从业务需求方面来说&#xff0c;区块链技术的发展已经是一种不可逆的趋势&a…

查找-二叉排序树

问题引入 【问题描述】 输入若干个整数建立二叉排序树,以0结束输入,在二叉排序树上查找关键字,删除指定关键字结点。 【输入形式】 (1)第一行,输入若干个整数,输入0结束输入; 如输入关键字 45 24 53 12 28 90 0 可建立如下二叉排序树 (2)第二行,输入两个整数,一…

GameOff2022参与有感

GameOff2022参与有感以及年度总结 厚颜无耻的用我们美术的立绘 GameOff— Redemption 很高兴在一个月的时间里面和大家一起完成了《Redemption》 比赛链接&#xff1a;Itch.io 百度云盘链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1ylK0QRr2lmkqi4JF1wsXtA 提…

【servelt原理_6_servlet核心接口和类】

servlet核心接口和类 在Servlet体系中&#xff0c;除了实现servlet接口,还可以通过继承GenericServlet或HttpServlet类实现编写1.Servlet接口 servlet接口是整个servlet的核心。它是所有Servlet类必须直接或者间接实现的一个接口&#xff0c;其内部需要实现的5个方法分别关乎…

基于flv.js的视频自动播放

1: html <video class"video-content" id"video">您的浏览器不支持 HTML5 video&#xff01; </video> 2: 创建flv实例并播放 let videoPlayer document.getElementById(video); //获取html if (flvJs.isSupported()) {//创建flv实例this.P…

音视频开发——FFmpeg技术点 【进阶一览】

概述 Fmpeg是一套领先的音视频多媒体处理开源框架&#xff0c;采用LGPL或GPL许可证。它提供了对音视频的采集、编码、解码、转码、音视频分离、合并、流化、过滤器等丰富的功能&#xff0c;包含了非常先进的音频/视频编解码库libavcodec&#xff0c;具有非常高的可移植性和编解…

[附源码]计算机毕业设计中小学课后延时服务管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Git 之 已有项目创建 git 仓库

Git 之 已有项目创建 git 仓库前言一、现在 github/gitee 中创建仓库二、在项目的文件夹当中 git bash here1.git init2. git remote add origin 仓库地址3. git pull origin master4. git add . git commit -m git push -u origin master前言 项目已经开始写了,但是还没有…

干货 | 数字经济创新创业——如何造就成功的职业生涯

下文整理自清华大学大数据能力提升项目能力提升模块课程“Innovation & Entrepreneurship for Digital Economy”&#xff08;数字经济创新创业课程)的精彩内容。主讲嘉宾&#xff1a;Kris Singh: CEO at SRII, Palo Alto, CaliforniaVisiting Professor of Tsinghua Unive…