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

news2024/11/20 9:14:57
定义于头文件 <algorithm>

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

判断一个序列是否为另一个序列的排列

std::is_permutation
template< class ForwardIt1, class ForwardIt2 >

bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,

                     ForwardIt2 first2 );
(1)(C++11 起)
(C++20 前)
template< class ForwardIt1, class ForwardIt2 >

constexpr bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,

                               ForwardIt2 first2 );
(C++20 起)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >

bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,

                     ForwardIt2 first2, BinaryPredicate p );
(2)(C++11 起)
(C++20 前)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >

constexpr bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,

                               ForwardIt2 first2, BinaryPredicate p );
(C++20 起)
template< class ForwardIt1, class ForwardIt2 >

bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,

                     ForwardIt2 first2, ForwardIt2 last2 );
(3)(C++14 起)
(C++20 前)
template< class ForwardIt1, class ForwardIt2 >

constexpr bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,

                               ForwardIt2 first2, ForwardIt2 last2 );
(C++20 起)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >

bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,
                     ForwardIt2 first2, ForwardIt2 last2,

                     BinaryPredicate p );
(4)(C++14 起)
(C++20 前)
template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >

constexpr bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,
                               ForwardIt2 first2, ForwardIt2 last2,

                               BinaryPredicate p );
(C++20 起)

 

若存在范围 [first1, last1) 中元素的排列,使得该范围等于 [first2,last2) ,则返回 true ,若不给出,则其中 last2 代表 first2 + (last1 - first1) 。

1,3) 用 operator== 比较元素。若它不是等价关系则行为未定义。

2,4) 用给定的二元谓词 p 比较元素。若它不是等价关系则行为未定义。

参数

first1, last1-要比较的元素范围
first2, last2-要比较的第二范围
p-若元素应被当做相等则返回 ​true 的二元谓词。

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

 bool pred(const Type &a, const Type &b);

Type 应是 ForwardIt1ForwardIt2 共同的值类型。签名不必有 const & ,但函数必须不修改传递给它的对象。 ​

类型要求
- ForwardIt1, ForwardIt2 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。
- ForwardIt1, ForwardIt2 必须拥有相同的 value_type 。

返回值

若范围 [first1, last1)[first2, last2) 的排列则为 true 。

复杂度

至多应用 O(N2) 次谓词,或若序列已经相等,则准确应用 N 次,其中 N=std::distance(first1, last1) 。

然而,若 ForwardIt1ForwardIt2 满足遗留随机访问迭代器 (LegacyRandomAccessIterator) 的要求且 std::distance(first1, last1) != std::distance(first2, last2) ,则不应用谓词。

可能的实现

template<class ForwardIt1, class ForwardIt2>
bool is_permutation(ForwardIt1 first, ForwardIt1 last,
                    ForwardIt2 d_first)
{
   // 跳过公共前缀
   std::tie(first, d_first) = std::mismatch(first, last, d_first);
   // 在 rest 上迭代,计数 [d_first, d_last) 中出现多少次
   // 每个来自 [first, last) 的元素
   if (first != last) {
       ForwardIt2 d_last = d_first;
       std::advance(d_last, std::distance(first, last));
       for (ForwardIt1 i = first; i != last; ++i) {
            if (i != std::find(first, i, *i)) continue; // 已经遇到此 *i
 
            auto m = std::count(d_first, d_last, *i);
            if (m==0 || std::count(i, last, *i) != m) {
                return false;
            }
        }
    }
    return true;
}

调用示例

#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;
        }
    }

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

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

int main()
{
    std::mt19937 g{std::random_device{}()};

    srand((unsigned)time(NULL));;

    std::cout << std::boolalpha;

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

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

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

    // 1,3) 用 operator== 比较元素。若它不是等价关系则行为未定义。
    size_t index = 0;
    while (true)
    {
        // 打印cells1
        std::cout << "cells1:   ";
        std::copy(cells1.begin(), cells1.end(), std::ostream_iterator<Cell>(std::cout, " "));

        std::cout << " || ";

        // 打印cells2
        std::cout << "cells2:   ";
        std::copy(cells2.begin(), cells2.end(), std::ostream_iterator<Cell>(std::cout, " "));

        if (std::is_permutation(cells1.begin(), cells1.end(), cells2.begin()))
        {
            std::cout << "is_permutation true" << std::endl;
            break;
        }

        std::cout << "is_permutation false" << std::endl;
        if (index > 6)
        {
            std::copy(cells1.begin(), cells1.end(), cells2.rbegin());
        }
        else
        {
            std::generate(cells2.begin(), cells2.end(), func1);
        }
        index++;
    }

    std::cout << std::endl << std::endl;

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

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

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

    // 2,4) 用给定的二元谓词 p 比较元素。若它不是等价关系则行为未定义。
    index = 0;
    while (true)
    {
        // 打印cells3
        std::cout << "cells3:   ";
        std::copy(cells3.begin(), cells3.end(), std::ostream_iterator<Cell>(std::cout, " "));

        std::cout << " || ";

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

        if (std::is_permutation(cells3.begin(), cells3.end(), cells4.begin(), binPre))
        {
            std::cout << "is_permutation true" << std::endl;
            break;
        }

        std::cout << "is_permutation false" << std::endl;
        if (index > 6)
        {
            std::copy(cells3.begin(), cells3.end(), cells4.rbegin());
        }
        else
        {
            std::generate(cells4.begin(), cells4.end(), func1);
        }
        index++;
    }

    return 0;
}

输出

 

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

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

相关文章

《记忆力心理学》5个方法 让你过目不忘

《记忆力心理学》 关于作者 赫尔曼•艾宾浩斯&#xff0c;西方心理学泰斗级人物&#xff0c;生活在19世纪的德国心理学家。他是最早用实验的方法对记忆进行量化研究的 人&#xff0c;最受人瞩目的贡献&#xff0c;就是发现了记忆保持曲线。 关于本书 这本书可以看作是记忆心…

全国职业院校技能大赛网络搭建与应用赛项——云平台底层的一些命令

1.列出运行的虚拟机 virsh list 2.列出所有的虚拟机virsh list --all 3.网络信息表&#xff08;20分&#xff09; 显示网络名及所在的vlan idopenstack network show Network10 -c name -c provider:segmentation_id openstack network show Network20 -c name -c provider:s…

学习->C++篇十九:四种智能指针及其实现

目录 为什么需要智能指针&#xff1f; 什么是内存泄露&#xff1f; 如何避免内存泄露&#xff1f; 什么是RAII&#xff1f; RAII有什么用&#xff1f; 智能指针的原理是什么&#xff1f; C的智能指针有哪些&#xff1f; auto_ptr unique_ptr shared_ptr weak_ptr 为什…

【第十五章 分库分表(垂直拆分,水平拆分),MyCat】

第十五章 分库分表&#xff08;垂直拆分&#xff0c;水平拆分&#xff09;&#xff0c;MyCat 1.分库分表&#xff1a; &#xff08;1&#xff09;介绍&#xff1a; ①采用单数据库进行数据存储&#xff0c;存在以下性能瓶颈&#xff1a; A.IO瓶颈&#xff1a;热点数据太多&…

第二证券|A股传奇董秘变身老板,公司IPO过会

A股传奇董秘何愿平卷土重来&#xff0c;但这次不是以董秘的身份。 12月20日&#xff0c;碧兴科技IPO获科创板上市委会议经过&#xff0c;其实控人正是A股曾经的传奇董秘何愿平。作为前碧水源董秘&#xff0c;何愿平曾多年连任A股身家最贵董秘。 二次创业过会 招股书显现&…

离散化算法

目录 算法原理 算法模板 1&#xff09;手工编码 2&#xff09;c用STL函数实现离散化 附录&#xff1a; 算法原理 给出一列数字&#xff0c;在有些情况下&#xff0c;这些数字的值得绝对大小不重要&#xff0c;而相对大小很重要。例如&#xff0c;对一个班级学生的成绩进行…

图片加水印怎么弄?这些图片加水印方法分享给你

相信很多小伙伴平常会喜欢将自己拍摄的作品上传到社交平台上与他人分享吧。然而有时会遇到自己辛苦拍摄的视频或者图片被他人盗用&#xff0c;甚至是获利的情况。其实想要避免自己的作品被他人盗用&#xff0c;我们可以在作品上面添加专属自己的水印&#xff0c;不仅可以给作品…

Java学生成绩管理系统

1、内容要求 编写一个学生成绩管理系统。学生的属性包括学号、姓名、年龄等。每个学生要学习若干课程&#xff0c;每门课程有平时成绩、期中考试成绩、期末考试成绩以及总评成绩&#xff0c;其中总评成绩平时成绩*30%期中成绩*30%期末成绩*40%。请先设计合理的类存放这些信息&a…

Span-level Bidirectional Network(2022 EMNLP)

论文题目&#xff08;Title&#xff09;&#xff1a;A Span-level Bidirectional Network for Aspect Sentiment Triplet Extraction 研究问题&#xff08;Question&#xff09;&#xff1a;方面情感三元组提取(ASTE)是一种新的细粒度情感分析任务&#xff0c;旨在从评论句中提…

【ML】机器学习中的十大深度学习算法

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

RTOS多任务切换实现

实现任务需要的基础知识 1、程序内部细节 通过分析C语言程序的编码会发现程序都是一些指令和数据。 什么是程序&#xff1f; 指令运行过程中的数据 2、常用汇编指令 汇编指令详解 3、ARM架构过程调用标准AAPCS 传参&#xff1a; 通过r0-r3传递&#xff0c;多于4个参数的部…

【矩阵论】6. 范数理论——基本概念——向量范数与矩阵范数

6.1 基本概念 6.1.1 向量范数 a. 模长&#xff08;二范数&#xff09; Cn中向量X(x1x2⋮xn)的模长为∣X∣(X,X)tr(AHA)∣x1∣2∣x2∣2⋯∣xn∣2C^n中向量 X\left( \begin{matrix} x_1\\x_2\\\vdots\\x_n \end{matrix} \right)的模长为 \vert X\vert\sqrt{(X,X)}\sqrt{tr(A^HA…

nginx+keeplived 实现高可用 Web 负载均衡

nginxkeeplived 实现高可用 Web 负载均衡 一、架构简介 在系统设计中&#xff0c;可以利用Nginx的反向代理和负载均衡实现后端应用的高可用性&#xff0c;同时我们还需要考虑Nginx的单点故障。如果Nginx所在服务器宕机&#xff0c;或者Nginx服务不可用就会造成整个系统的不可…

鸡蛋车的控制律

这个老头像幽灵&#xff0c; ​拿个鸡蛋来炸群。 ​只见动画不见车&#xff0c; ​骗人无果还丢人&#xff01; 温州一个做汽车驾驶模拟器的&#xff0c;在重庆为我约了美女&#xff0c;为鸡蛋车站台。他掏空口袋砸我&#xff0c;材料、工资、车马&#xff0c;都是他担。 余姚一…

代码随想录算法训练营第十天(字符串)| 232.用栈实现队列,225. 用队列实现栈

代码随想录算法训练营第九天&#xff08;字符串&#xff09;| 232.用栈实现队列&#xff0c;225. 用队列实现栈 232. 用栈实现队列 大家可以先看视频&#xff0c;了解一下模拟的过程&#xff0c;然后写代码会轻松很多。 题目链接/文章讲解/视频讲解&#xff1a; 看到题目的…

react笔记_08生命周期

目录生命周期(旧)生命周期componentWillMountcomponetdidMountshouldComponentUpdatecomponentWillUpdatecomponentDidUpdatecomponentWillUnmountcomponentWillReceiveProps组件的挂载、更新、销毁案例1渲染过程更新过程1-通过setState去修改数据更新过程2-通过forceUpdate强制…

用Python分析《阿凡达·水之道》的豆瓣短评

《阿凡达水之道》于2022年12月16日上映。第一部的口碑、评分等都非常高&#xff0c;第二部是否能延续呢&#xff0c;本文获取了该电影的豆瓣短评&#xff0c;进行了初步的分析&#xff0c;看下观众都是如何评价的。 数据获取 打开豆瓣首页&#xff0c;搜索电影名&#xff0c;进…

Spring(三): 使用注解来存储和读取Bean对象

目录一、存储Bean对象1.1 配置扫描路径1.2 使用注解存储Bean对象1.3 通过上下文读取Bean对象1.4 Bean命名规则1.5 方法注解 Bean1.5 重命名Bean二、获取Bean对象2.1 属性注入2.2 Setter注入2.3 构造方法注入2.4 Resource注解2.5 Resource注解中name参数的作用一、存储Bean对象 …

说明书丨艾美捷Annexin-V-Cy3凋亡检测试剂盒

Cy3标记的重组人膜联蛋白V显示亮红色荧光&#xff08;Ex&#xff08;max&#xff09;:543nm&#xff1b;Em&#xff08;最大值&#xff09;&#xff1a;570nm&#xff09;。 艾美捷Annexin-V-Cy3凋亡检测试剂盒化学性质&#xff1a; Applications: Flow Cytometry, Fluorescen…

C++【修理之路】初识string

这里写目录标题为什么学习string类&#xff1f;标准库中的string类string的定义转换为C风格的字符串string类的输出和输出访问字符串中的字符字符串的拼接string 字符串的增删改查总结为什么学习string类&#xff1f; C语言中&#xff0c;字符串是以’\0’结尾的一些字符的集合…