【C++】list的使用(下)

在这里插入图片描述

🔥个人主页: Forcible Bug Maker
🔥专栏: STL || C++

目录

  • 前言
  • 🔥操作list对象的接口函数(opeartions)
    • ==splice==
    • ==remove==
    • ==remove_if==
    • ==unique==
    • ==merge==
    • ==sort==
    • ==reverse==
  • 结语

前言

本篇博客主要内容:STL库中list用法的讲解

让我们接着上一篇博文的内容继续,进入list最后一个模块,操作list对象的接口函数。

🔥操作list对象的接口函数(opeartions)

在这里插入图片描述

splice

在这里插入图片描述

从x中转移元素到容器中,并将它们插入到指定的位置(功能相当于剪切)。

这实际上是将这些元素插入到容器中,并从x中移除它们,从而改变两个容器的大小。这个操作不涉及任何元素的构造或销毁。元素被转移,无论x是左值还是右值,或者value_type是否支持移动构造。

entire list (1)

void splice (iterator position, list& x);

single element (2)

void splice (iterator position, list& x, iterator i);

element range (3)

void splice (iterator position, list& x, iterator first, iterator last);

第一个版本(1)将x中的所有元素转移到容器中position指向的元素之前。
第二个版本(2)仅将x中由i指向的元素转移到容器中position指向的元素之前。
第三个版本(3)将x中迭代器范围[first,last)中的元素转移到容器中position指向的元素之前。

代码案例:

// splicing lists
#include <iostream>
#include <list>

int main ()
{
  std::list<int> mylist1, mylist2;
  std::list<int>::iterator it;

  // set some initial values:
  for (int i=1; i<=4; ++i)
     mylist1.push_back(i);      // mylist1: 1 2 3 4

  for (int i=1; i<=3; ++i)
     mylist2.push_back(i*10);   // mylist2: 10 20 30

  it = mylist1.begin();
  ++it;                         // 迭代器指向 2

  mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
                                // mylist2 (empty)
                                // "it" 迭代器仍然指向 2 (第五个元素)
                                          
  mylist2.splice (mylist2.begin(),mylist1, it);
                                // mylist1: 1 10 20 30 3 4
                                // mylist2: 2
                                // "it"迭代器现在失效了
  it = mylist1.begin();
  std::advance(it,3);           // "it" 迭代器现在指向 30

  mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
                                // mylist1: 30 3 4 1 10 20

  std::cout << "mylist1 contains:";
  for (it=mylist1.begin(); it!=mylist1.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "mylist2 contains:";
  for (it=mylist2.begin(); it!=mylist2.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

在这里插入图片描述

remove

在这里插入图片描述

void remove (const value_type& val);

该函数(list::remove)从容器中移除所有与给定值val相等的元素。这会调用这些对象的析构函数,并通过移除的元素数量来减少容器的大小。

与成员函数list::erase不同,list::erase是通过元素的位置(使用迭代器)来删除元素的,而list::remove则是通过元素的值来删除元素的。

还存在一个类似的函数list::remove_if,它允许通过除了相等性比较之外的条件来确定是否移除一个元素。

代码案例:

// remove from list
#include <iostream>
#include <list>

int main()
{
    int myints[] = { 17,89,7,14 };
    std::list<int> mylist(myints, myints + 4);

    mylist.remove(89);

    std::cout << "mylist contains:";
    for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

在这里插入图片描述

remove_if

在这里插入图片描述

template <class Predicate>
  void remove_if (Predicate pred);

该函数从容器中移除所有使得所给定谓词(Predicate)pred返回true的元素。这会调用这些对象的析构函数,并通过移除的元素数量来减少容器的大小。

对于容器中的每个元素(其中i是指向该元素的迭代器),该函数会调用pred(*i)。列表中任何使得pred(*i)返回true的元素都将从容器中移除。

pred:可以是一个函数指针函数对象,它接受一个与forward_list对象中元素类型相同的值,并返回一个布尔值。对于要从容器中移除的值,该谓词返回true;对于保留在容器中的值,返回false。这样,你可以通过提供一个这样的谓词来定制forward_list中元素的移除规则。

代码案例:

// list::remove_if
#include <iostream>
#include <list>

// 函数:
bool single_digit(const int& value) { return (value < 10); }

// 仿函数,一个类伪装成的函数:
struct is_odd {
    bool operator() (const int& value) { return (value % 2) == 1; }
};

int main()
{
    int myints[] = { 15,36,7,17,20,39,4,1 };
    std::list<int> mylist(myints, myints + 8);   // 15 36 7 17 20 39 4 1

    mylist.remove_if(single_digit);           // 15 36 17 20 39

    mylist.remove_if(is_odd());               // 36 20

    std::cout << "mylist contains:";
    for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

在这里插入图片描述

unique

在这里插入图片描述
(1)

void unique();

(2)

template <class BinaryPredicate>
  void unique (BinaryPredicate binary_pred);

没有参数的版本(1)会移除容器中每个连续相等元素组中除了第一个元素以外的所有元素

请注意,当一个元素只有当它与它前面紧挨着的元素相等时,才会从列表中移除。因此,这个函数特别适用于已排序的列表

第二个版本(2)接受一个特定的比较函数作为参数,用于确定元素的“唯一性”。实际上,可以实现任何行为(而不仅仅是相等性比较),但请注意,该函数会对所有元素对(其中i是元素迭代器,从第二个元素开始)调用binary_pred(*i,*(i-1)),如果谓词返回true,则将i从列表中移除。

被移除的元素的空间会被释放。

代码案例:

// list::unique
#include <iostream>
#include <cmath>
#include <list>

// a binary predicate implemented as a function:
bool same_integral_part(double first, double second)
{
    return (int(first) == int(second));
}

// a binary predicate implemented as a class:
struct is_near {
    bool operator() (double first, double second)
    {
        return (fabs(first - second) < 5.0);
    }
};

int main()
{
    double mydoubles[] = { 12.15,  2.72, 73.0,  12.77,  3.14,
                         12.77, 73.35, 72.25, 15.3,  72.25 };
    std::list<double> mylist(mydoubles, mydoubles + 10);

    mylist.sort();             //  2.72,  3.14, 12.15, 12.77, 12.77,
    // 15.3,  72.25, 72.25, 73.0,  73.35

    mylist.unique();           //  2.72,  3.14, 12.15, 12.77
    // 15.3,  72.25, 73.0,  73.35

    mylist.unique(same_integral_part);  //  2.72,  3.14, 12.15
    // 15.3,  72.25, 73.0

    mylist.unique(is_near());           //  2.72, 12.15, 72.25

    std::cout << "mylist contains:";
    for (std::list<double>::iterator it = mylist.begin(); it != mylist.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

在这里插入图片描述

merge

在这里插入图片描述
(1)

void merge (list& x);

(2)

template <class Compare>
  void merge (list& x, Compare comp);

合并有序链表

该函数通过将x中的所有元素按其各自的有序位置转移到容器中,来将x合并到列表中(两个容器都应当已经是有序的)。

这实际上移除了x中的所有元素(x变为空),并将它们插入到容器中的有序位置(容器的大小会增加转移的元素数量)。这个操作不需要构造或销毁任何元素:它们是被转移的,无论x是左值还是右值,或者value_type是否支持移动构造。

带有两个参数的模板版本(2)具有相同的行为,但是它们接受一个特定的谓词(comp)来执行元素之间的比较操作。这个比较应当产生元素的一个严格弱序(即,一个一致的传递性比较,不考虑其自反性)。

这个函数要求列表容器在调用之前已经根据值(或根据comp)对其元素进行了排序。对于无序列表的替代方案,请参见list::splice

假设存在这样的排序,x中的每个元素都根据其值插入到由<运算符或comp定义的严格弱序所对应的位置。结果中,等价元素的顺序是稳定的(即,等价元素保持它们在调用之前的相对顺序,并且现有元素优先于从x中插入的等价元素)。

如果&x == this(即,尝试将一个列表合并到它自己中),则该函数什么也不做。

代码案例:

// list::merge
#include <iostream>
#include <list>

// compare only integral part:
bool mycomparison(double first, double second)
{
    return (int(first) < int(second));
}

int main()
{
    std::list<double> first, second;

    first.push_back(3.1);
    first.push_back(2.2);
    first.push_back(2.9);

    second.push_back(3.7);
    second.push_back(7.1);
    second.push_back(1.4);

    first.sort();
    second.sort();

    first.merge(second);

    // (second is now empty)

    second.push_back(2.1);

    first.merge(second, mycomparison);

    std::cout << "first contains:";
    for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

在这里插入图片描述

sort

在这里插入图片描述
(1)

void sort();

(2)

template <class Compare>
  void sort (Compare comp);

排序list对象中的元素

该函数会对列表中的元素进行排序,改变它们在容器中的位置

排序操作通过应用一个算法来完成,该算法使用 < 运算符(在版本 (1) 中)或 comp(在版本 (2) 中)来比较元素。这个比较应当产生元素的一个严格弱序(即,一个一致的传递性比较,不考虑其自反性)。

排序后,等价元素的顺序是稳定的:即,等价元素保持它们在调用之前的相对顺序。

整个操作不涉及任何元素对象的构造、销毁或复制。元素在容器内部进行移动。

#include<iostream>
#include<list>

class great
{
public:
	bool operator()(int x, int y)
	{
		return x > y;
	}
};

int main()
{
	std::list<int> lt({ 9,3,4,7,1 });
	for (auto e : lt)std::cout << e << " ";
	std::cout << std::endl;

	lt.sort();
	for (auto e : lt)std::cout << e << " ";
	std::cout << std::endl;

	lt.sort(great());
	for (auto e : lt)std::cout << e << " ";
	std::cout << std::endl;
	
	return 0;
}

在这里插入图片描述

该排序的底层是堆排序,速度会比快排慢上2~3倍。同时algorithm中的sort不支持排序list对象的元素,因为链表由于其自生结构特点难以实现快排的逻辑。

reverse

在这里插入图片描述

void reverse();

反转list对象中的元素

代码案例:

#include<iostream>
#include<list>

int main()
{
	std::list<int> lt({ 9,3,4,7,1 });
	for (auto e : lt)std::cout << e << " ";
	std::cout << std::endl;

	lt.reverse();
	for (auto e : lt)std::cout << e << " ";
	std::cout << std::endl;

	return 0;
}

在这里插入图片描述

结语

本篇文章所讲到的list内容出自于同一个模块,由于其排序和合并的方式涉及到了仿函数的传递,所以内容和篇幅稍微会大一些。相信学完本篇内容之后,能对list的使用和C++有更充分的了解。
博主后续还会产出更多有趣的的内容,感谢大家的支持。♥

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能合约引领:探索Web3的商业革新之路

随着区块链技术的迅速发展&#xff0c;智能合约作为其重要应用之一&#xff0c;正在逐步改变着商业世界的格局。Web3作为下一代互联网的代表&#xff0c;正引领着智能合约在商业领域的广泛应用和创新。本文将深入探讨智能合约在Web3中的作用&#xff0c;以及智能合约如何引领着…

「计网」网络初识

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;计网 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 网络初识 &#x1f349;IP 地址 & 端口号&#x1f349;网络协议&#x1f34c;TCP/IP 网络协议 &#x1f349;封装和分用&#x1f349…

Xcode设置cocoapods库的最低兼容版本

目录 前言 1.使用cocoapods遇到的问题 2.解决办法 1.用法解释 1. config.build_settings: 2.IPHONEOS_DEPLOYMENT_TARGET 2.使用实例 3.注意事项 1.一致性 2.pod版本 前言 这篇文章主要是介绍如何设置cocoapods三方库如何设置最低兼容的版本。 1.使用cocoapods遇到的…

小红书图片视频下载利器,无水印!

在刷小红书时&#xff0c;总能看到一些博主发的好看的壁纸或者视频&#xff0c;想下载下来做头像或者设置为手机电脑的桌面。不过众所周知&#xff0c;直接保存的图片和视频都是有水印的&#xff0c;那如何去掉水印呢&#xff1f; 有些朋友肯定说&#xff0c;我知道有去水印的…

如何区分解析亚马逊网站产品搜索结果页HTM代码中广告位( Sponsored)和自然位的产品ASIN及排名

在开发亚马逊产品广告排名插件的时候需要通过页面HTML代码分别找出属于广告位和自然搜索结果的产品ASIN及排名&#xff0c;所以需要找到区分广告位和自然搜索结果的HTML代码属性&#xff1a; 所有搜索结果页的产品不管是广告位还是自然位&#xff0c;都包括在 标签里&#xff…

服务器数据恢复—服务器raid常见故障表现原因解决方案

RAID&#xff08;磁盘阵列&#xff09;是一种将多块物理硬盘整合成一个虚拟存储的技术&#xff0c;raid模块相当于一个存储管理的中间层&#xff0c;上层接收并执行操作系统及文件系统的数据读写指令&#xff0c;下层管理数据在各个物理硬盘上的存储及读写。相对于单独的物理硬…

kali中切换python版本

kali中切换python版本 在日常使用的过程中&#xff0c;可以通过一些工具来做打靶环境&#xff0c;或者工具的启动&#xff0c;都和python关联&#xff0c;而有时存在工具安装&#xff0c;或者运行的时候出现报错&#xff0c;这时候极大可能是因为我们本地的kali中python的版本不…

安装pytorch深度学习模型时要知道自己的电脑显卡是否支持CUDA

安装pytorch深度学习模型时要知道自己的电脑显卡是否支持CUDA&#xff0c;如何知道自己的显卡是否支持呢&#xff1f;可以去下面的网站&#xff0c;打开后就可以见到如下图所示&#xff1a; CUDA | 支持的GPU | GeForce (nvidia.cn)

【Mac】XMind for mac(XMind思维导图)v24.04.10311软件介绍和安装教程

软件介绍 XMind for Mac是一款功能强大的思维导图软件。它具有以下主要特点&#xff1a; 1.多样化的思维导图功能&#xff1a;XMind for Mac提供了丰富的思维导图编辑功能&#xff0c;用户可以创建各种类型的思维导图&#xff0c;包括组织结构图、逻辑图、时间轴图等&#xf…

基于优化Morlet小波的一维信号瞬态特征提取方法(MATLAB R2018A)

小波分析方法近些年逐步得到发展的一门数学分析技术&#xff0c;它对许多学科都有十分重要的影响。与傅立叶变换等其他传统方法相比&#xff0c;小波分解的方法中所用的小波基有着多种多样的结构&#xff0c;总结来说又包括正交小波系与非正交小波系。正交小波在信号处理领域目…

超越传统插值:利用深度学习提升视频帧率与清晰度

视频帧率的提升是视频处理领域中一个重要问题&#xff0c;它直接影响到视频的流畅度和观感。随着技术的发展&#xff0c;人们对于视频质量的要求越来越高&#xff0c;尤其是在捕捉快速运动场景时&#xff0c;高帧率视频能够提供更加清晰和连贯的视觉效果。然而&#xff0c;传统…

(2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X

Lumina-T2X: Transforming Text into Any Modality, Resolution, and Duration via Flow-based Large Diffusion Transformers 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 …

Dynamics CRM 修改新建记录的CreatedOn字段值

CRM在创建新记录时&#xff0c;一些系统属性例如创建者、创建时间是取当前创建记录的人以及当前的时间&#xff0c;而有时这些属性需要更改&#xff0c;例如创建时间&#xff0c;这个场景更多的用在数据迁移的时候&#xff0c;老数据有他的原始创建时间&#xff0c;不能因为迁移…

python在cmd中运行.exe文件时报错:不是内部或外部命令,也不是可运行的程序或批处理文件。的解决办法

添加系统环境变量&#xff1a; 设置环境变量&#xff0c;在用户变量里面添加 【PATH&#xff1a;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Windows\SysWOW64】 在系统变量里面添加,【变量名&#xff1a;ComSpec】 【变量值&#xff1a;%SystemRoo…

springboot+vue的养老院管理系统

免费获取方式↓↓↓ 项目介绍036&#xff1a; http://localhost:8080/ admin 123456 测试用户 123456 测试护工 123456 二、技术栈 所有场景都支持 适合零基础小白练手和实战&#xff1b;适合二次开发&#xff1b; 项目图片概览&#xff1a; 以上是对本项目的界面预览。 界…

比较3维空间中4个点的不同结构

在4*4*4的3维空间中&#xff0c;取4个点共有635376种可能&#xff0c;有209个结构&#xff0c;继续按旋转对称分类则只有55个不同的结构。如其中的4t12 4个点在同一个平面&#xff0c;有1个点与其中的3个点不在同一行也不在同一列&#xff0c;这样的位置不止一个 这两个结构都是…

JCR一区级 | Matlab实现TCN-BiGRU-MATT时间卷积双向门控循环单元多特征分类预测

JCR一区级 | Matlab实现TCN-BiGRU-MATT时间卷积双向门控循环单元多特征分类预测 目录 JCR一区级 | Matlab实现TCN-BiGRU-MATT时间卷积双向门控循环单元多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现TCN-BiGRU-MATT时间卷积双向门控循环单元多…

【产品经理】总篇章

引言: 在最近频繁的产品职位面试中&#xff0c;我深刻体会到了作为产品需要的不仅仅是对市场和技术的敏锐洞察&#xff0c;更多的是在复杂多变的环境中&#xff0c;如何运用沟通、领导力和决策能力来引导产品从概念走向市场。这一系列博客将分享我多年经历和所学到的所以知识&a…

golang线程池ants-四种使用方法

目录 1、ants介绍 2、使用方式汇总 3、各种使用方式详解 3.1 默认池 3.2 普通模式 3.3 带参函数 3.4 多池多协程 4、总结 1、ants介绍 众所周知&#xff0c;goroutine相比于线程来说&#xff0c;更加轻量、资源占用更少、无线程上下文切换等优势&#xff0c;但是也不能…

知识计算概述

文章目录 知识计算研究现状技术发展趋势 知识计算 随着知识图谱技术及应用的不断发展&#xff0c;图谱质量和知识完备性成为影响知识图谱应用的两大重要难题&#xff0c;以图谱质量提升、潜在关系挖掘与补全、知识统计与知识推理作为主要研究内容的知识计算成为知识图谱应用的重…