c++ 11标准模板(STL) std::map(二)

定义于头文件<map>

template<

    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >

> class map;
(1)
namespace pmr {

    template <class Key, class T, class Compare = std::less<Key>>
    using map = std::map<Key, T, Compare,
                         std::pmr::polymorphic_allocator<std::pair<const Key,T>>>

}
(2)(C++17 起)

std::map 是有序键值对容器,它的元素的键是唯一的。用比较函数 Compare 排序键。搜索、移除和插入操作拥有对数复杂度。 map 通常实现为红黑树。

在每个标准库使用比较 (Compare) 概念的位置,以等价关系检验唯一性。不精确而言,若二个对象 ab 互相比较不小于对方 : !comp(a, b) && !comp(b, a) ,则认为它们等价(非唯一)。

std::map 满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、关联容器 (AssociativeContainer) 和可逆容器 (ReversibleContainer) 的要求。

成员函数

构造 map

std::map<Key,T,Compare,Allocator>::map
map();

explicit map( const Compare& comp,

              const Allocator& alloc = Allocator() );
(1)

explicit map( const Allocator& alloc );

(1)(C++11 起)
template< class InputIt >

map( InputIt first, InputIt last,
     const Compare& comp = Compare(),

     const Allocator& alloc = Allocator() );
(2)
template< class InputIt >

map( InputIt first, InputIt last,

     const Allocator& alloc );
(C++14 起)

map( const map& other );

(3)

map( const map& other, const Allocator& alloc );

(3)(C++11 起)

map( map&& other );

(4)(C++11 起)

map( map&& other, const Allocator& alloc );

(4)(C++11 起)
map( std::initializer_list<value_type> init,

     const Compare& comp = Compare(),

     const Allocator& alloc = Allocator() );
(5)(C++11 起)

map( std::initializer_list<value_type> init,
     const Allocator& );

(C++14 起)

 从各种数据源构造新容器,可选地使用用户提供的分配器 alloc 或比较函数对象 comp

1) 构造空容器。

2) 构造容器,使之拥有范围 [first, last) 的内容。若范围中的多个元素拥有比较等价的关键,则插入哪个元素是未指定的(待决的 LWG2844 )。

3) 复制构造函数。构造容器,使之拥有 other 的内容副本。若不提供 alloc ,则通过调用 std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator()) 获得分配器。

4) 移动构造函数。用移动语义构造容器,使之拥有 other 的内容。若不提供 alloc ,则从属于 other 的分配器移动构造分配器

5) 构造容器,使之拥有 initializer_list init 的内容。若范围中的多个元素拥有比较等价的关键,则插入哪个元素是未指定的(待决的 LWG2844 )。

参数

alloc-用于此容器所有内存分配的分配器
comp-用于所有关键比较的比较函数对象
first, last-复制元素来源的范围
other-要用作源以初始化容器元素的另一容器
init-用以初始化容器元素的 initializer_list
类型要求
- InputIt 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。
- Compare 必须满足比较 (Compare) 的要求。
- Allocator 必须满足分配器 (Allocator) 的要求。

复杂度

1) 常数。

2) N log(N) ,其中通常有 N = std::distance(first, last) ,若范围已为 value_comp() 所排序则与 N 成线性。

3) 与 other 的大小成线性。

4) 常数。若给定 alloc 且 alloc != other.get_allocator() 则为线性。

5) N log(N) ,其中通常有 N = init.size()) ,若 init 已按照 value_comp() 排序则与 N 成线性 。

异常

Allocator::allocate 的调用可能抛出。

析构 map

std::map<Key,T,Compare,Allocator>::~map

~map();

销毁容器。调用元素的析构函数,然后解分配所用的存储。注意,若元素是指针,则不销毁所指向的对象。

复杂度

与容器大小成线性。

调用示例

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <map>
#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
    {
        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;
    }
};

struct myCompare
{
    bool operator()(const int &a, const int &b)
    {
        return a < b;
    }
};

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

std::ostream &operator<<(std::ostream &os, const std::pair<const int, Cell> &pCell)
{
    os << pCell.first << "-" << pCell.second;
    return os;
}

int main()
{
    auto genKey = []()
    {
        return std::rand() % 10 + 100;
    };

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

    //1) 构造空容器。
    std::map<int, Cell> map1;
    std::cout << "map1 is empty: " << map1.empty() << std::endl;
    for (size_t index = 0; index < 5; index++)
    {
        map1.insert({genKey(), generate()});
    }
    std::cout << std::endl;

    //2) 构造容器,使之拥有范围 [first, last) 的内容。
    std::map<int, Cell> map2(map1.begin(), map1.end());
    std::cout << "map2:    ";
    std::copy(map2.begin(), map2.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    // 逆序
    std::map<int, Cell, std::greater<int>> map8(map1.begin(), map1.end());
    std::cout << "map8:    ";
    std::copy(map8.begin(), map8.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    //3) 复制构造函数。构造容器,使之拥有 other 的内容副本。
    std::map<int, Cell> map3(map2);
    std::cout << "map3:    ";
    std::copy(map3.begin(), map3.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::map<int, Cell, std::greater<int>> map9(map8);
    std::cout << "map9:    ";
    std::copy(map9.begin(), map9.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    //4) 移动构造函数。用移动语义构造容器,使之拥有 other 的内容。
    std::map<int, Cell> map4(std::move(map2));
    std::cout << "map4:    ";
    std::copy(map4.begin(), map4.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << "map2(move) is empty: " << map2.empty() << std::endl;
    std::map<int, Cell, std::greater<int>> map10(std::move(map8));
    std::cout << "map10:   ";
    std::copy(map10.begin(), map10.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << "map8(move) is empty: " << map10.empty() << std::endl;
    std::cout << std::endl;

    //5) 构造容器,使之拥有 initializer_list init 的内容。
    std::map<int, Cell> map5({{genKey(), generate()}, {genKey(), generate()},
        {genKey(), generate()}, {genKey(), generate()}, {genKey(), generate()}});
    std::cout << "map5:    ";
    std::copy(map5.begin(), map5.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::map<int, Cell, std::greater<int>> map11({{genKey(), generate()}, {genKey(), generate()},
        {genKey(), generate()}, {genKey(), generate()}, {genKey(), generate()}});
    std::cout << "map11:   ";
    std::copy(map11.begin(), map11.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    //使用系统key比较函数
    std::map<int, Cell, std::greater<int>> map6({{genKey(), generate()}, {genKey(), generate()},
        {genKey(), generate()}, {genKey(), generate()}, {genKey(), generate()}});
    std::cout << "map6:    ";
    std::copy(map6.begin(), map6.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    //使用自定义key比较函数
    std::map<int, Cell, myCompare> map7({{genKey(), generate()}, {genKey(), generate()},
        {genKey(), generate()}, {genKey(), generate()}, {genKey(), generate()}});
    std::cout << "map7:    ";
    std::copy(map7.begin(), map7.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    return 0;
}

输出

 

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

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

相关文章

想劝大家别去外包,干了5年,彻底废了......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近5年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四…

提示msvcr120.dll丢失怎么办?由于找不到msvcr120.dll如何修复?

msvcr120.dll 是 Microsoft Visual C 文件中的一个重要组件。它是一种动态链接库&#xff0c;包含了很多函数&#xff0c;提供了许多基础的 C 运行时支持。这个库文件的主要功能是提供 C 应用程序的运行时环境&#xff0c;它是一些常用的 C 运行时库文件的集合。这些库包括了 m…

【Netty】Netty 程序引导类(九)

文章目录 前言一、引导程序类二、AbstractBootStrap 抽象类三、Bootstrap 类四、ServerBootstrap 类五、引导服务器5.1、 实例化引导程序类5.2、设置 EventLoopGroup5.3、指定 Channel 类型5.4、指定 ChannelHandler5.5、设置 Channel 选项5.6、绑定端口启动服务 六、引导客户端…

语法速通 uni-app随笔【uni-app】【微信小程序】【vue】

1、微信小程序 1.1、wx 小程序 工程目录 其中&#xff0c; pages目录/index目录【必有】&#xff1a; index.js 编写业务逻辑 【初始数据&#xff0c;生命周期函数】 index.json 编写配置 index.wxml 编写模板 【可理解为本页html】 index.wxss 【可理解为本页css】 1.2、wx…

cdn配置(超详细+图解+原理)

具体的详细配置在右侧目录翻到“三”&#xff0c;前面的一二是将原理 以腾讯云的cdn为例&#xff0c;其它家的大同小异 一、cdn作用和配置思路 &#xff08;一&#xff09;cdn作用 1.加速访问 cdn服务通常有多个节点缓存&#xff0c;用户可以就近获取&#xff0c;延迟较低 …

如何运行Node.js脚本及读取环境变量

目录 1、如何从CLI 运行Node.js 脚本 2、将字符串作为参数传递到节点&#xff0c;而不是文件路径 3、自动重新启动应用程序 4、如何从Node.js中读取环境变量 1、如何从CLI 运行Node.js 脚本 运行Node.js程序的通常方法是运行全局可用的Node命令&#xff08;一旦安装Node.js…

Linux---文本处理命令(grep、wc、管道符 |)

1. grep命令 grep命令能够在一个或多个文件中&#xff0c;搜索某一特定的字符模式&#xff08;也就是正则表达式&#xff09;&#xff0c;此模式可以 是单一的字符、字符串、单词或句子。 注意&#xff1a;在基本正则表达式中&#xff0c;如通配符 *、、{、|、( 和 )等&#…

蓝桥杯--挖地雷

没有白走的路&#xff0c;每一步都算数&#x1f388;&#x1f388;&#x1f388; 题目&#xff1a; 已知有很多的地窖&#xff0c;每一个地窖中又藏着很多的地雷&#xff0c;每个地窖之间都存在着相连性&#xff0c;但是不是任意的地窖都是相连的&#xff0c;要求我们找出一次能…

深度学习—目标检测标注数据集

深度学习之目标检测 PASCAL数据集 PASCAL VOC挑战赛&#xff08;The PASCAL Visual Object Classes&#xff09;是一个世界级的计算机视觉挑战赛&#xff0c;PASCAL全称&#xff1a;Pattern Analysis&#xff0c;Statical Modeling and Computational Learning&#xff0c;是…

native层函数没有导出时,如何获得相应函数地址?

前言 每次App重新运行后native函数加载的绝对地址是会变化的&#xff0c;唯一不变的是函数相对于基地址的偏移&#xff0c;因此我们可以在获取模块的基地址后加上固定的偏移地址获取相应函数的地址&#xff0c;Frida中也正好提供了这种方式&#xff1a;先通过Module.findBaseA…

Augmented Language Models(增强语言模型)

Augmented Language Models: A Survey 先上地址&#xff1a;https://arxiv.org/pdf/2302.07842.pdf 概率论难以支撑通用人工智能技术的诞生。—— Yann LeCun LLMs取得的巨大进展不再多说&#xff0c;它目前被诟病最多的问题是其会提供非事实但看似可信答案&#xff0c;即幻觉…

MySQL之索引初步

1. 索引概念 数据库是⽤来存储数据&#xff0c;在互联⽹应⽤中数据库中存储的数据可能会很多(⼤数据)&#xff0c; 数据表中数据的查询速度会随着数据量的增⻓而逐渐变慢 &#xff0c;从⽽导致响应⽤户请求的速度变慢——⽤户体验差&#xff0c;我们如何提⾼数据库的查询效率呢…

第一个servlet的程序

文章目录 一.Hello World的程序1.创建项目2.引入依赖3.创建目录4.编写代码5.打包程序6.部署程序7.验证程序 二.简化部署方式1.下载插件2.配置smart Tomcat插件3.测试插件 三.常见的servelt问题出现 404出现 405出现 500出现 "空白页面"出现 "无法访问此网站&quo…

【数据结构】队列详解

本篇要分享的内容是队列的解析和增删查改的使用&#xff0c;以下为本篇目录 目录 1.队列的概念及结构 2.队列的结构 3.队列的初始化 4.队列空间释放 5.入队 6.出队 7.获取队头和队尾元素 获取对头 获取队尾 8.计算队列元素 9.判空 11.本篇所有代码展示 Queue.c Q…

一、尚医通手机登录

文章目录 一、登录需求1、登录效果2、登录需求 二、登录1&#xff0c;搭建service-user模块1.1 搭建service-user模块1.2 修改配置1.3 启动类1.4 配置网关 2、添加用户基础类2.1 添加model2.2 添加Mapper2.3 添加service接口及实现类2.4 添加controller 3、登录api接口3.1 添加…

FPGA——HLS入门-LED闪烁仿真

系列文章目录 文章目录 系列文章目录一、HLS介绍1、什么是HLS2、与VHDL/Verilog有什么关系?3、关键技术局限性 二、Vivado HLS - LED闪烁仿真1、项目配置2、C仿真3、联合仿真 三、总结 一、HLS介绍 1、什么是HLS HLS就是高综合&#xff08;High level Synthesis&#xff09;…

公网远程访问本地jupyter notebook服务 - 内网穿透

文章目录 前言视频教程1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 转载自cpolar的文章&#xff1a;公网远程访问Jupyter Notebook【Cpolar内网穿透】 前言 Jupyter Notebook&am…

最优化方法Python计算:一元函数搜索算法——牛顿法

设函数 f ( x ) f(x) f(x)&#xff0c;在 [ a , b ] [a,b] [a,b]上二阶连续可微且有唯一的最小值点 x 0 x_0 x0​。由于 f ( x ) f(x) f(x)是 [ a , b ] [a,b] [a,b]上的单峰函数&#xff0c;故 f ′ ′ ( x ) > 0 f(x)>0 f′′(x)>0&#xff0c; x ∈ ( a , b ) x\in…

MyBatis快速入门

目录 一、什么是MyBatis 二、MyBatis的学习要领 三、搭建第一个MyBatis 3.1 创建数据库和表 3.2 添加MyBatis框架支持 3.2.1 老项目添加MyBatis 3.2.2 新项目去添加MyBatis 3.3 设置MyBatis配置信息 3.3.1 设置数据库连接的相关信息 3.3.2 设置MyBatis xml保存路径 和…

vue-cli4+vant+rem+sass+vuex+axios封装+webpack搭建前端项目

移动端项目模板 基于 vue-cli4.0 webpack 4 vant ui sass rem 适配方案axios 封装&#xff0c;构建手机端模板脚手架 启动项目 git clone https://github.com/teach-tian/h5-vue-cli4.gitcd h5-vue-cli4npm installnpm run serve✅ 配置多环境变量 package.json 里的 s…