C++ std::list的merge()使用与分析

看到《C++标准库第2版》对list::merge()的相关介绍,令我有点迷糊,特意敲代码验了一下不同情况的调用结果。

《C++标准库第2版》对list::merge()的相关介绍

list::merge()定义

merge()的作用就是将两个list合并在一起,函数有2个版本:

  • c1.merge(c2)------------->这个版本含糊,将c2合入c1中,但合并后元素是怎么排序的呢?下文主要分析这个版本的不同调用结果
  • c1.merge(c2, op)--------->这个版本比较简单,就是将c2的内容合入到c1中,然后按op()排序

c1.merge(c2)调用情况分析

  • 前提:有两个list,内容分别如下:

  • 情况一:c1默认排序,c2不排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c1.sort(); //默认升序排序myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:合并后没有按c1的默认升序排序

  • 情况二:c1不排序,c2默认排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c2.sort(); //默认升序排序myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:合并后没有按c2的默认升序排序

  • 情况三:c1默认排序,c2默认排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c1.sort(); //默认升序排序c2.sort(); //默认升序排序myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:合并后也能按默认升序排序

  • 情况四:c1默认排序,将c1赋值给c2,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c1.sort(); //默认升序排序c2 = c1;myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:可以看到,c1赋值给c2,使得c2也具有了与c1一样的默认排序,两者合并后,仍能按默认升序排序,结果与情况三结果相似。


下面使用自定义的降序规则(op())来排序

    //降序比较auto op = [](int first, int second) {return first > second;};

情况五:c1自定义降序排序,c2不排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c1.sort(op);myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:合并后没有按c1的自定义降序排序,与情况一相似

情况六:c1不排序,c2自定义降序排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c2.sort(op);myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:合并后没有按c2的自定义降序排序,与情况二相似

情况七:c1自定义降序排序,c2自定义降序排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c1.sort(op);c2.sort(op);myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:合并后,其结果仅仅是将c2放到了c1的末端,c1段、c2段数据仍是合并前的顺序,这与情况三有差异

 情况八:c1自定义降序排序,c2默认排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c1.sort(op);c2.sort();myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

结果:合并后,没有按c1的自定义降序排序,也没有按c2的默认排序,与情况二相似

情况九:c1自定义降序排序,将c1赋值给c2,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };list<int> c2{ 10,11,99,13,14,15 };cout << "-----------原始数据-----------" << endl;myPrinter(c1, c2);cout << "-----------排序后数据-----------" << endl;c1.sort(op);c2 = c1;myPrinter(c1, c2);cout << "-----------合并后数据-----------" << endl;c1.merge(c2);myPrinter(c1, c2);

 

结果:合并后,其结果仅仅是将c2放到了c1的末端,c1段、c2段数据仍是合并前的顺序,这与情况七相同,但与情况三有差异

结论

因为合并后的顺序情况多变,所以如果希望合并后结果按某种规则排序,建议使用c1.merge(c2, op),指明合并后的排序规则。

当然,如果c1,c2都是默认排序,则可以直接使用c1.merge(c2),即上文提到的情况三。

附:示例的辅助函数

template <class T>
void printfList(const T& _Container, const char* _Delim)
{std::copy(_Container.cbegin(), _Container.cend(), std::ostream_iterator<T::value_type>(cout, _Delim));cout << endl;
}void myPrinter(const list<int>& c1, const list<int>& c2)
{cout << "c1:";printfList(c1, " ");cout << "c2:";printfList(c2, " ");cout << "----------------------" << endl << endl;
}

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

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

相关文章

蓝桥杯(3.12)

1064: 【模板】埃氏筛法 import java.util.Scanner;public class Main{static final int N 2000010;static boolean[] vis new boolean[N];public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();vis[0] true;vis[1] true;for…

深入浅出FISCO BCOS:区块链底层平台

苏泽 大家好 这里是苏泽 一个钟爱区块链技术的后端开发者 本篇专栏 ←持续记录本人自学两年走过无数弯路的智能合约学习笔记和经验总结 如果喜欢拜托三连支持~ 我前面有补充相关的区块链的知识 如果没有了解的话 可能部分概念或名词会不懂哦 建议先了解一波再来看~http://t.c…

算法-二分与差分-503.借教室

题目 思路 代码不超时&#xff1a;限制在10的8次方以内&#xff1b;线段树能处理的数据上限是10^5二分&#xff1a;具有二段性&#xff0c;第一个订单不满足&#xff0c;后面的订单也不用去考虑差分&#xff08;前缀和的逆运算&#xff09;&#xff1a;题目的要求是将一个区间…

Shell学习 - 2.22 Shell数学计算(算术运算,加减乘除运算)

如果要执行算术运算&#xff08;数学计算&#xff09;&#xff0c;就离不开各种运算符号&#xff0c;和其他编程语言类似&#xff0c;Shell 也有很多算术运算符&#xff0c;下面就给大家介绍一下常见的 Shell 算术运算符&#xff0c;如下表所示。 Shell 算术运算符一览表 算术运…

【leetcode热题】反转字符串中的单词

给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意&#xff1a;输入字符串 s中可能会存在前导空格、尾随…

VulnHub - DarkHole

希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers Blog DarkHole 靶机下载地址&#xff1a;DarkHole: 1 ~ VulnHub 0x01 信息收集 Nmap扫描目标主机&#xf…

深度学习——第10章 优化神经网络:如何防止过拟合(DNN)

第10章 优化神经网络:如何防止过拟合(DNN) 目录 10.1 什么是过拟合 10.2 L1、L2正则化 10.3 L2正则化的物理解释 10.4 Dropout正则化 10.5 其它正则化技巧 10.6 总结 上一课,我们一步步搭建了一个深层神经网络来实现图片的分类。结果显示,随着网络层数加深,隐藏层数…

C语言自学笔记3-----C语言运算符及优先级

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符&#xff0c;并提供了以下类型的运算符&#xff1a; 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 杂项运算符 算术运算符 下表显示了 C 语言支持的所有算术运算符。 假设变量 A 的…

Kafka 实现之接口设计 —— 生产者 API、消费者 API

目录 一. 前言 二. 生产者 API 三. 消费者 API 3.1. 低级别 API 3.2. 高级别 API 一. 前言 Kafka 强大的应用程序层的基础是用于访问存储的两个基本 API&#xff0c;即用于写入事件的生产者 API和用于读取事件的消费者 API。在这两个 API 之上构建了用于集成和处理的 API。…

在域控批量导出用户及其所在路径的信息

在Windows Server的Active Directory环境中&#xff0c;要批量导出用户及其所在OU&#xff08;组织单位&#xff09;的信息&#xff0c;可以使用PowerShell命令来实现。以下是一个简单的示例&#xff1a; Get-ADUser -Filter * -Properties CanonicalName | Select-Object Nam…

力扣-160. 相交链表(双指针)

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&a…

ARTS Week 20

Algorithm 本周的算法题为 1222. 可以攻击国王的皇后 在一个 下标从 0 开始 的 8 x 8 棋盘上&#xff0c;可能有多个黑皇后和一个白国王。 给你一个二维整数数组 queens&#xff0c;其中 queens[i] [xQueeni, yQueeni] 表示第 i 个黑皇后在棋盘上的位置。还给你一个长度为 2 的…

【JVM】字节码指令 invokevirtual

在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;invokevirtual 是一个字节码指令&#xff0c;用于调用对象实例的方法。它的主要作用是执行对象的虚方法调用&#xff0c;遵循Java语言中的动态分派机制。 例如&#xff0c;假设我们有以下Java代码&#xff1a; Java 1…

AI与广告创意:大模型在广告生成中的应用与挑战

AI与广告创意&#xff1a;大模型在广告生成中的应用与挑战 摘要&#xff1a; 本文将探讨AI大模型在广告创意生成中的应用&#xff0c;并分析其面临的挑战。 引言&#xff1a; 在当今信息爆炸的时代&#xff0c;广告创意生成的重要性不言而喻。广告创意需要吸引目标受众的注…

多维时序 | Matlab实现VMD-CNN-BiLSTM变分模态分解结合卷积神经网络结合双向长短期记忆神经网络多变量时间序列预测

多维时序 | Matlab实现VMD-CNN-BiLSTM变分模态分解结合卷积神经网络结合双向长短期记忆神经网络多变量时间序列预测 目录 多维时序 | Matlab实现VMD-CNN-BiLSTM变分模态分解结合卷积神经网络结合双向长短期记忆神经网络多变量时间序列预测预测效果基本介绍程序设计参考资料 预测…

stm32是用标准库还是hal库?

我大学几年一直都是使用标准库&#xff0c;然后17年毕业第一份工作转为HAL库&#xff0c;主要也是公司需求没办法。然后之后的数年我都是建议转HAL库&#xff0c;并不是这个库有多好&#xff0c;相反小问题很多&#xff0c;但是有一个&#xff0c;这是官方一直在开发维护的库&a…

软件开发秘籍:打造高效的分支管理策略

版本控制策略&#xff1a;如何制定合理的分支管理策略 引言 版本控制是软件开发中至关重要的一环&#xff0c;而合理的分支管理策略则是版本控制成功的关键。本文将介绍如何制定合理的分支管理策略&#xff0c;并通过实际案例和技巧&#xff0c;帮助读者更好地理解和应用。 …

SpringBoot3快速入门

目录 一、快速创建项目 二、手动创建一个工程 一、快速创建项目 1、使用官网提供的spring组件创建一个springboot3工程&#xff0c;springboot3要使用JDK17以上的版本 选择配置点击finish&#xff0c;刷新maven 创建一个controller层&#xff0c;写一个demo&#xff0c;点击运…

学习vue3第四节(ref以及ref相关api)

主要记录以下api&#xff1a;ref()、isRef()、unref()、 shallowRef()、triggerRef()、customRef() 1、ref() 定义 接受一个内部值&#xff0c;返回一个响应式的、可更改的 ref 对象&#xff0c;此对象只有一个指向其内部值的属性 .value&#xff0c;.value属性用于追踪并且存…

二十、HTML

一、什么是HTML 超文本标记语言&#xff0c;不是一种编程语言&#xff0c;而是一种标记语言&#xff0c;描述网页的语言&#xff0c;HTML使用标签描述网页中图片、文本、音乐、视频、超链接等。 二、常用标签 1、标题标签 <h1>一级标题</h1> 1-6 2、段落标签<p&…