c++11 标准模板(STL)(std::forward_list)(十三)

news2024/11/15 15:53:56

定义于头文件 <forward_list>

template<

    class T,
    class Allocator = std::allocator<T>

> class forward_list;
(1)(C++11 起)
namespace pmr {

    template <class T>
    using forward_list = std::forward_list<T, std::pmr::polymorphic_allocator<T>>;

}
(2)(C++17 起)

std::forward_list 是支持从容器中的任何位置快速插入和移除元素的容器。不支持快速随机访问。它实现为单链表,且实质上与其在 C 中实现相比无任何开销。与 std::list 相比,此容器提在不需要双向迭代时提供更有效地利用空间的存储。

在链表内或跨数个链表添加、移除和移动元素,不会非法化当前指代链表中其他元素的迭代器。然而,在从链表移除元素(通过 erase_after )时,指代对应元素的迭代器或引用会被非法化。

std::forward_list 满足容器 (Container) (除了 operator== 的复杂度始终为线性和 size 函数)、具分配器容器 (AllocatorAwareContainer) 和序列容器 (SequenceContainer) 的要求。
 

操作

移除满足特定标准的元素

std::forward_list<T,Allocator>::remove, remove_if

void remove( const T& value );

(C++11 起)
(C++20 前)

size_type remove( const T& value );

(C++20 起)

template< class UnaryPredicate >
void remove_if( UnaryPredicate p );

(C++11 起)
(C++20 前)

template< class UnaryPredicate >
size_type remove_if( UnaryPredicate p );

(C++20 起)

移除所有满足特定标准的元素。第一版本移除所有等于 value 的元素,第二版本移除所有谓词 p 对它返回 true 的元素。

参数

value-要移除的元素的值
p-若应该移除该元素则返回 ​true 的一元谓词。

对每个(可为 const 的) T 类型参数 v ,表达式 p(v) 必须可转换为 bool ,无关乎值类别,而且必须不修改 v 。从而不允许 T& 类型参数,亦不允许 T ,除非对 T 而言移动等价于复制 (C++11 起)。 ​

返回值

(无)

(C++20 前)

移除的元素数。

(C++20 起)

复杂度

与容器大小成线性

 

将该链表的所有元素的顺序反转

std::forward_list<T,Allocator>::reverse

void reverse() noexcept;

(C++11 起)

逆转容器中的元素顺序。不非法化任何引用或迭代器。

参数

(无)

返回值

(无)

复杂度

与容器大小成线性

 

删除连续的重复元素

std::forward_list<T,Allocator>::unique

void unique();

(1)(C++11 起)
(C++20 前)

size_type unique();

(C++20 起)

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

(2)(C++11 起)
(C++20 前)

template< class BinaryPredicate >
size_type unique( BinaryPredicate p );

(C++20 起)

从容器移除所有相继的重复元素。只留下相等元素组中的第一个元素。第一版本用 operator== 比较元素,第二版本用二元谓词 p 比较元素

参数

p-若元素应被当做相等则返回 ​true 的二元谓词。

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

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

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

返回值

(无)

(C++20 前)

移除的元素数。

(C++20 起)

复杂度

与容器大小成线性

 

对元素进行排序

std::forward_list<T,Allocator>::sort

void sort();

(1)(C++11 起)

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

(2)(C++11 起)

以升序排序元素。保持相等元素的顺序。第一版本用 operator< 比较元素,第二版本用给定的比较函数 comp

若抛出异常,则 *this 中元素顺序未指定。

参数

comp-比较函数对象(即满足比较 (Compare) 概念的对象),若第一参数小于(即序于)第二参数则返回 ​true 。

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

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

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

返回值

(无)

复杂度

大约 N log N 次比较,其中 N 是表中的元素数。

注意

std::sort 要求随机访问迭代器且不能用于 forward_list 。此函数与 std::sort 的区别在于,它不要求 forward_list 的元素类型可交换,保留所有迭代器的值,并进行稳定排序。

调用示例

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>

using namespace std;

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator +(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

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

    Cell &operator ++()
    {
        x += 1;
        y += 1;
        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::cout << std::boolalpha;

    std::mt19937 g{std::random_device{}()};
    srand((unsigned)time(NULL));

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

    std::forward_list<Cell> forward_list1(6);
    std::generate(forward_list1.begin(), forward_list1.end(), generate);
    std::cout << "forward_list1:            ";
    std::copy(forward_list1.begin(), forward_list1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //移除所有满足特定标准的元素。第一版本移除所有等于 value 的元素
    forward_list1.remove(*(forward_list1.begin()));
    std::cout << "forward_list1 remove:     ";
    std::copy(forward_list1.begin(), forward_list1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

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

    //移除所有满足特定标准的元素。第二版本移除所有谓词 p 对它返回 true 的元素。
    forward_list1.remove_if(std::bind(func_remove, std::placeholders::_1, *(forward_list1.begin())));
    std::cout << "forward_list1 remove_if:  ";
    std::copy(forward_list1.begin(), forward_list1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;


    std::forward_list<Cell> forward_list2(6);
    std::generate(forward_list2.begin(), forward_list2.end(), generate);
    std::cout << "forward_list2:            ";
    std::copy(forward_list2.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //逆转容器中的元素顺序。不非法化任何引用或迭代器。
    forward_list2.reverse();
    std::cout << "forward_list2 reverse:    ";
    std::copy(forward_list2.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << std::endl;


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

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

    for (size_t index = 0; index < 3; index++)
    {
        std::forward_list<Cell> forward_list(6);
        std::generate(forward_list.begin(), forward_list.end(), generate);
        std::cout << "forward_list " << index + 3 << ":           ";
        std::copy(forward_list.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
        std::cout << std::endl;

        //对元素进行排序
        if (index % 2 == 0)
        {
            // 升序
            forward_list.sort();
        }
        else
        {
            // 降序
            forward_list.sort(func_sort);
        }

        std::cout << "forward_list " << index + 3 << " sort:      ";
        std::copy(forward_list.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
        std::cout << std::endl;

        //从容器移除所有相继的重复元素。
        if (index % 2 == 0)
        {
            //第一版本用 operator== 比较元素
            forward_list.unique();
        }
        else
        {
            //第二版本用二元谓词 p 比较元素
            forward_list.unique(func_unique);
        }

        std::cout << "forward_list " << index + 3 << " unique:    ";
        std::copy(forward_list.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
        std::cout << std::endl;
    }

    return 0;
}

输出

 

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

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

相关文章

湖仓一体电商项目(一):项目背景和架构介绍

文章目录 项目背景和架构介绍 一、项目背景介绍

vue iframe展示pdf请求接口

<iframe:src"pdfUrl"style"border: none; width: 100%; height: calc(100% - 10px)"frameborder"0">iframe是一个非常好用的标签&#xff0c;用于文件的展示src地址可以一个访问后端的一个地址&#xff08;https://mp.csdn.net/mp_blog/cr…

day25|51.N皇后、37.解数独

51.N皇后 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案…

sylixos input子系统学习、调试记录

Input 子系统框架图&#xff1a; Xinput设备驱动层&#xff1a; 将所有设备抽象成xmes、xkbd设备&#xff0c;上层程序&#xff08;如Qt&#xff09;就可以像操作普通字符设备一样操作它们。 Xinput核心处理层&#xff1a; 从物理设备取得输入事件&#xff0c;然后通过消息队…

校招失败后,在小公司熬了 2 年终于进了字节跳动,竭尽全力....

其实两年前校招的时候就往字节投了一次简历&#xff0c;结果很明显凉了&#xff0c;随后这个理想就被暂时放下了&#xff0c;但是这个种子一直埋在心里这两年除了工作以外&#xff0c;也会坚持写博客&#xff0c;也因此结识了很多优秀的小伙伴&#xff0c;从他们身上学到了特别…

【软件测试面试】国企6年测试经验大D佬分析总结测试团队面试问题......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 国企测试大佬测试面…

一起自学SLAM算法:11.5 强化学习与自主导航

连载文章&#xff0c;长期更新&#xff0c;欢迎关注&#xff1a; 强化学习&#xff08;Reinforcement Learning&#xff0c;RL&#xff09;[21]属于机器学习领域的一个分支&#xff0c;其学习目标是获得最大回报。在10.3.1节中已经讨论过&#xff0c;机器学习过程主要涉及四个要…

【Java并发详解】

参考书目&#xff1a; 堆和方法区中的数据是可以被共享的 堆中的数据是被栈中的变量所持用的&#xff0c;栈是线程隔离的&#xff0c;每个线程私有一个栈&#xff0c;所以栈中的数据不共享 调用a方法时&#xff0c;jvm会给a方法创建一块内存区&#xff0c;让其入栈&#xff…

UIRecorder安装、录制、回放

Github地址&#xff1a;https://github.com/alibaba/uirecorder/blob/master/README_zh-cn.md 支持 android ios 和pc端的自动化脚本录制。无线native app(Android, iOS)录制是&#xff0c;是基于macaca实现的&#xff1a;https://macacajs.com 整体组成架构 UIRecorder录制功…

Dubbo服务开发和运行流程【java面试】

(1)问题分析&#xff1a;考官主要想考核dubbo的原理&#xff0c;还有dubbo在项目中的使用。(2)核心答案讲解&#xff1a;dubbo服务开发流程&#xff1a;maven工程中pom文件先导入dubbo依赖jar包搭建zookeeper注册中心写好服务端工程并配置dubbo服务端配置&#xff0c;并关联上z…

Spring概览——最佳入门实践

1、Spring Framework Spring 基础框架&#xff0c;可以视为 Spring 基础设施&#xff0c;基本上任何其他 Spring 项目都是以 Spring Framework 为基础的。 1.1、Spring Framework特性 建议新手先看完的最佳实践&#xff0c;再回头看这一段。 非侵入式&#xff1a;使用 Spri…

Java List按照某字段去重

Java List按照某字段去重嘚吧嘚distinct示例一示例二根据某个字段去重Collectors.collectingAndThen()嘚吧嘚 Java8流的新类java.util.stream.Collectors实现了java.util.stream.Collector接口&#xff0c;同时又提供了大量的方法对流(stream)的元素执行各种统计操作。 distinc…

实战: 跨年烟花代码的实现(附源码)

目录 前言 一、pandas是什么&#xff1f; 二、代码结构 1.介绍主html代码 2. js文件介绍 GameCanvas.js script.js 运行效果 前言 本文章将介绍跨年烟花代码的实现以及源代码 提示&#xff1a;以下是本篇文章正文内容 一、pandas是什么&#xff1f; 示例&#xff1a;pandas …

css3-动画

目录语法转换平移旋转缩放复合属性的顺序问题过渡动画帧动画案例案例1-热点图dot(缩放)案例2-热点图dot(缩放)案例3-开红包(旋转)问题问题1-transform不起作用问题2 - 过渡动画不起效果语法 转换 css3中的转换允许我们对元素进行旋转、缩放、移动或倾斜。它分为2D转换 或 3D转…

开箱即用的物联网平台-IoTLink

物联网平台是物联网生态系统的重要组成部分&#xff0c;也是一个快速增长的市场&#xff0c;物联网平台为企业提供了巨大的价值&#xff0c;使他们能够降低开发成本、加速启动和简化流程。 一个完整的物联网系统需要硬件、连接、软件、用户界面等。在较高的层面上&#xff0c;…

menuconfig的执行过程

menuconfig &#xff08;1&#xff09;首先在uboot源码顶层目录下的Makefile文件中查找config&#xff08;%表示省略&#xff09; &#xff08;2&#xff09;执行make menuconfig&#xff0c;分别打印输出$(MAKE)、$(bulid)、$可知其对应的内容&#xff0c;如上图所示 总结&a…

用docker部署django后台作为webstack的后台管理系统-其二

0 序言 在之前的博客中&#xff1a; 用docker部署webstack导航网站-其一https://blog.csdn.net/qq_41938259/article/details/128736551?spm1001.2014.3001.5501我成功的将webstack官方推荐的docker容器部署了出来&#xff0c;但是官方的docker容器后端使用的是PHP&#xff0…

08_FreeRTOS列表和列表项讲解

目录 列表和列表项的简介 列表 列表项 迷你列表项 列表和列表项的关系 列表相关API函数介绍 初始化列表vListInitialise函数详解 列表项的初始化函数vListInitialiseItem函数 列表项的插入vListInsert函数 列表项末尾插入vListInsertEnd函数 列表项的删除函数uxLis…

零入门容器云网络实战-5->路由知识总结

本篇文章主要用于收集、整理、总结路由相关知识点。 1、路由分为几种&#xff1f; 直连路由静态路由&#xff08;基本静态路由&#xff0c;等价静态路由&#xff0c;活动静态路由&#xff0c;缺省静态路由&#xff09;动态路由 通过路由协议从相邻路由器学习到的。路由协议&am…

一,SpringMVC入门

0 MVC设计模式 View&#xff08;视图&#xff09;&#xff1a;页面&#xff08;jsp、html&#xff09;&#xff0c;接收用户数据和显示结果。 Controller&#xff08;控制器&#xff09;&#xff1a;action&#xff0c;接收请求&#xff0c;决定程序执行流程。 Model&#xf…