容器库(9)-std::multimap

2024-02-21 00:44
文章标签 容器 std multimap

本文主要是介绍容器库(9)-std::multimap,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

std::multimap是一种关联容器,包含键值对的已排序的列表。和std::map不同的是,std::multimap允许重复的key值。搜索、移除和插入操作具有对数复杂度。

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

本文章的代码库:

https://gitee.com/gamestorm577/CppStd

成员函数

构造、析构和赋值

构造函数

可以用迭代器、另一个multimap或者元素列表来构造一个multimap。代码示例:

std::multimap<int, float> m1{{1, 1.5f}, {1, 1.2f}, {2, 2.5f}};
std::multimap<int, float> m2(m1.begin(), std::next(m1.begin(), 1));
std::multimap<int, float> m3(m2);
std::multimap<int, float> tmp(m1);
std::multimap<int, float> m4(std::move(tmp));std::cout << "m1 size = " << m1.size() << std::endl;
std::cout << "m2 size = " << m2.size() << std::endl;
std::cout << "m3 size = " << m3.size() << std::endl;
std::cout << "m4 size = " << m4.size() << std::endl;

输出结果:

m1 size = 3
m2 size = 1
m3 size = 1
m4 size = 3

析构函数

销毁multimap时会调用各元素的析构函数。代码示例:

struct MyStruct
{MyStruct(int i): Index(i){}~MyStruct(){std::cout << "destruct, Index = " << Index << std::endl;}int Index = 0;
};std::multimap<int, MyStruct> m = {{1, 15}, {1, 20}, {2, 25}};
std::cout << "end" << std::endl;

输出结果:

destruct, Index = 25
destruct, Index = 20
destruct, Index = 15
end
destruct, Index = 25
destruct, Index = 20
destruct, Index = 15

赋值函数

可以用另一个multimap或者元素列表给multimap赋值。代码示例:

std::multimap<int, float> tmp{{1, 1.1f}, {1, 1.2f}, {3, 1.3f}};
std::multimap<int, float> m1;
std::multimap<int, float> m2;m1 = tmp;
m2 = {{1, 1.1f}, {1, 1.2f}};
std::cout << "m1 size = " << m1.size() << std::endl;
std::cout << "m2 size = " << m2.size() << std::endl;

输出结果:

m1 size = 3
m2 size = 2

迭代器

接口begin、cbegin指向multimap起始的迭代器,end、cend指向末尾的迭代器。rbegin、crbegin指向起始的逆向迭代器,rend、crend指向末尾的逆向迭代器。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
for (auto iter = m.begin(); iter != m.end(); ++iter)
{iter->second += 20.f;
}for (auto iter = m.cbegin(); iter != m.cend(); ++iter)
{std::cout << "key " << iter->first << " value = " << iter->second<< std::endl;
}

输出结果:

key 1 value = 21.1
key 1 value = 21.2
key 2 value = 21.3

容量

empty

检查multimap是否为空。代码示例:

std::multimap<int, float> m1;
std::multimap<int, float> m2{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
std::cout << std::boolalpha;
std::cout << "m1 empty: " << m1.empty() << std::endl;
std::cout << "m2 empty: " << m2.empty() << std::endl;

输出结果:

m1 empty: true
m2 empty: false

size

获取元素的个数。代码示例:

std::multimap<int, float> m1;
std::multimap<int, float> m2{{1, 1.1f}, {1, 1.2f}, {3, 1.3f}};
std::cout << "m1 size = " << m1.size() << std::endl;
std::cout << "m2 size = " << m2.size() << std::endl;

输出结果:

m1 size = 0
m2 size = 3

max_size

返回可以容纳的最大元素数。代码示例:

std::multimap<int, int> m1;
std::multimap<double, double> m2;
std::cout << "m1 max_size = " << m1.max_size() << std::endl;
std::cout << "m2 max_size = " << m2.max_size() << std::endl;

输出结果:

m1 max_size = 461168601842738790
m2 max_size = 384307168202282325

修改器

clear

清除所有的元素。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {3, 1.3f}};
std::cout << "m size = " << m.size() << std::endl;
m.clear();
std::cout << "m size = " << m.size() << std::endl;

输出结果:

m size = 3
m size = 0

insert

插入元素,参数可以是元素、迭代器或者元素节点。代码示例:

std::multimap<int, float> m{{1, 1.1f}};m.insert({1, 12.5f});
m.insert({1, 12.5f});
m.insert({2, 12.5f});
std::cout << "m size = " << m.size() << std::endl;std::multimap<int, float> tmp{{1, 1.1f}, {2, 1.2f}, {2, 1.3f}};
m.insert(tmp.begin(), tmp.end());
std::cout << "m size = " << m.size() << std::endl;

输出结果:

m size = 4
m size = 7

emplace

构造一对键值到multimap中。代码示例:

std::multimap<int, float> m;
m.emplace(1, 12.5f);
m.emplace(1, 12.5f);
m.emplace(2, 12.5f);
std::cout << "m size = " << m.size() << std::endl;

输出结果:

m size = 3

emplace_hint

向multimap中尽可能靠近hint之前的位置插入新元素:

template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args);

不同的hint会导致插入元素的效率不同。代码示例:

auto timer = [](std::function<std::size_t()> func, std::string tag) -> void
{auto start = std::chrono::system_clock::now();std::size_t size = func();auto end = std::chrono::system_clock::now();std::chrono::duration<double, std::milli> time = end - start;std::cout << tag << ", size: " << size << ", use time: " << time.count()<< std::endl;
};const int count = 1000000;auto multimap_emplace = [=]() -> std::size_t
{std::multimap<int, char> m;for (int i = 0; i < count; ++i){m.emplace(i, 'a');}return m.size();
};auto multimap_emplace_hint1 = [=]() -> std::size_t
{std::multimap<int, char> m;auto iter = m.begin();for (int i = 0; i < count; ++i){m.emplace_hint(iter, i, 'a');iter = m.end();}return m.size();
};auto multimap_emplace_hint2 = [=]() -> std::size_t
{std::multimap<int, char> m;auto iter = m.begin();for (int i = 0; i < count; ++i){m.emplace_hint(iter, i, 'a');iter = m.begin();}return m.size();
};auto multimap_emplace_hint3 = [=]() -> std::size_t
{std::multimap<int, char> m;auto iter = m.begin();for (int i = 0; i < count; ++i){iter = m.emplace_hint(iter, i, 'a');}return m.size();
};timer(multimap_emplace, "multimap_emplace");
timer(multimap_emplace_hint1, "multimap_emplace_hint1");
timer(multimap_emplace_hint2, "multimap_emplace_hint2");
timer(multimap_emplace_hint3, "multimap_emplace_hint3");

输出结果:

multimap_emplace, size: 1000000, use time: 1686.37
multimap_emplace_hint1, size: 1000000, use time: 777.029
multimap_emplace_hint2, size: 1000000, use time: 1246.12
multimap_emplace_hint3, size: 1000000, use time: 1177.37

erase

移除指定位置或者指定key的容器。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {1, 1.3f}, {2, 2.1f},{2, 2.2f}, {3, 3.1f}, {3, 3.2f}};
std::cout << "m size = " << m.size() << std::endl;
m.erase(m.begin());
std::cout << "m size = " << m.size() << std::endl;
m.erase(m.begin(), std::next(m.begin(), 2));
std::cout << "m size = " << m.size() << std::endl;
m.erase(3);
std::cout << "m size = " << m.size() << std::endl;

输出结果:

m size = 7
m size = 6
m size = 4
m size = 2

swap

和另一个multimap交换元素内容。代码示例:

std::multimap<int, float> m1{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
std::multimap<int, float> m2{{1, 4.1f}, {2, 4.2f}};
m1.swap(m2);
std::cout << "m1 size = " << m1.size() << std::endl;
std::cout << "m2 size = " << m2.size() << std::endl;

输出结果:

m1 size = 2
m2 size = 3

extract

提取multimap中的某个元素节点,提取后multimap不再拥有该元素。如果有多个元素和指定的key值相同,则提取第一个。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}, {2, 1.4f}};
std::cout << "m size: " << m.size() << std::endl;
m.extract(1);
std::cout << "m size: " << m.size() << std::endl;
auto node = m.extract(2);
std::cout << "m size: " << m.size() << std::endl;
std::cout << "node value: " << node.mapped() << std::endl;
m.insert(std::move(node));
std::cout << "m size: " << m.size() << std::endl;

输出结果:

m size: 4
m size: 3
m size: 2
node value: 1.3
m size: 3

merge

合并另一个map或者multimap。代码示例:

std::multimap<int, float> m1{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
std::map<int, float> m2{{1, 1.1f}, {2, 1.2f}};
std::multimap<int, float> m3{{2, 1.1f}, {2, 1.2f}};
std::cout << "m1 size = " << m1.size() << std::endl;
m1.merge(m2);
std::cout << "m1 size = " << m1.size() << std::endl;
m1.merge(m3);
std::cout << "m1 size = " << m1.size() << std::endl;

输出结果:

m1 size = 3
m1 size = 5
m1 size = 7

查找

count

返回匹配key值的元素个数。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
std::cout << "m key 1 count: " << m.count(1) << std::endl;
std::cout << "m key 2 count: " << m.count(2) << std::endl;
std::cout << "m key 3 count: " << m.count(3) << std::endl;

输出结果:

m key 1 count: 2
m key 2 count: 1
m key 3 count: 0

find

返回匹配key值的迭代器。如果有多个配备的元素,那么返回任意一个。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
std::cout << "m key 1 value is: " << m.find(1)->second << std::endl;

输出结果:

m key 1 value is: 1.1

contains

检查是否包含某个key值,返回布尔值。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
std::cout << std::boolalpha;
std::cout << "m contains 1: " << m.contains(1) << std::endl;
std::cout << "m contains 3: " << m.contains(3) << std::endl;

输出结果:

m contains 1: true
m contains 3: false

lower_bound

返回首个大于等于给定键值的迭代器。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 2.1f}, {2, 2.2f},{2, 2.3f}, {3, 3.1f}, {3, 3.2f}};
auto iter = m.lower_bound(2);
std::cout << "key: " << iter->first << ", value: " << iter->second<< std::endl;

输出结果:

key: 2, value: 2.1

upper_bound

返回首个大于给定键值的迭代器。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 2.1f}, {2, 2.2f},{2, 2.3f}, {3, 3.1f}, {3, 3.2f}};
auto iter = m.upper_bound(2);
std::cout << "key: " << iter->first << ", value: " << iter->second<< std::endl;

输出结果:

key: 3, value: 3.1

equal_range

返回一对迭代器,分别是lower_bound和upper_range的结果。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 2.1f}, {2, 2.2f},{2, 2.3f}, {3, 3.1f}, {3, 3.2f}};
auto [iter1, iter2] = m.equal_range(2);
std::cout << "iter1 key: " << iter1->first << ", value: " << iter1->second<< std::endl;
std::cout << "iter2 key: " << iter2->first << ", value: " << iter2->second<< std::endl;

输出结果:

iter1 key: 2, value: 2.1
iter2 key: 3, value: 3.1

观察器

key_comp

返回用于比较key值的函数。代码示例:

struct MyComp
{bool operator()(int lhs, int rhs) const{std::cout << "MyComp" << std::endl;return true;}
};std::multimap<int, std::string, MyComp> m;
auto comp = m.key_comp();
comp(10, 20);

输出结果:

MyComp

value_comp

返回用于比较键值对的函数,参数是键值对,但实际是比较的key值。代码示例:

struct MyComp
{bool operator()(int lhs, int rhs) const{std::cout << "MyComp" << std::endl;return true;}
};std::multimap<int, std::string, MyComp> m;
auto comp = m.value_comp();
comp(std::make_pair(1, "a"), std::make_pair(2, "b"));

输出结果:

MyComp

非成员函数

比较运算符

operator==,!=,<,<=,>,>=用于比较两个multimap。代码示例:

std::multimap<int, float> m1{{1, 1.1f}, {1, 1.2f}, {2, 1.3f}};
std::multimap<int, float> m2{{1, 1.1f}, {1, 1.2f}};
std::cout << std::boolalpha;
std::cout << "m1 == m2: " << (m1 == m2) << std::endl;
std::cout << "m1 != m2: " << (m1 != m2) << std::endl;
std::cout << "m1 <  m2: " << (m1 < m2) << std::endl;
std::cout << "m1 <= m2: " << (m1 <= m2) << std::endl;
std::cout << "m1 >  m2: " << (m1 > m2) << std::endl;
std::cout << "m1 >= m2: " << (m1 >= m2) << std::endl;

输出结果:

m1 == m2: false
m1 != m2: true
m1 <  m2: false
m1 <= m2: false
m1 >  m2: true
m1 >= m2: true

swap

交换两个multimap的元素内容。代码示例:

std::multimap<int, float> m1{{1, 1.1f}, {2, 1.2f}, {3, 1.3f}};
std::multimap<int, float> m2{{1, 1.1f}, {2, 1.2f}};
std::swap(m1, m2);
std::cout << "m1 size = " << m1.size() << std::endl;
std::cout << "m2 size = " << m2.size() << std::endl;

输出结果:

m1 size = 2
m2 size = 3

erase_if

删除满足要求的元素。代码示例:

std::multimap<int, float> m{{1, 1.1f}, {1, 1.2f}, {2, 21.3f}, {2, 21.5f}};
std::erase_if(m,[](const std::pair<int, float>& pair) -> bool{return pair.second > 10.f;});for (auto& item : m)
{std::cout << "key: " << item.first << ", value: " << item.second<< std::endl;
}

输出结果:

key: 1, value: 1.1
key: 1, value: 1.2

这篇关于容器库(9)-std::multimap的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/730070

相关文章

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

C++ STL关联容器Set与集合论入门

1. 简介 Set(集合)属于关联式容器,也是STL中最实用的容器,关联式容器依据特定的排序准则,自动为其元素排序。Set集合的底层使用一颗红黑树,其属于一种非线性的数据结构,每一次插入数据都会自动进行排序,注意,不是需要排序时再排序,而是每一次插入数据的时候其都会自动进行排序。因此,Set中的元素总是顺序的。 Set的性质有:数据自动进行排序且数据唯一,是一种集合元素,允许进行数学上的集合相

Spring容器上下文

目录 一 什么是spring容器上下文 二 spring容器上下文可以做什么 三 如何使用 1.实现ApplicationContextAware接口 2.代码测试 一 什么是spring容器上下文 你可以把它理解成就是spring容器,它主要用于管理Bean对象,包括bean的生命周期,bean的注入等等。 二 spring容器上下文可以做什么 我们刚刚上面

Java 入门指南:Java 并发编程 —— 并发容器 ConcurrentLinkedDeque

文章目录 ConcurrentLinkedDeque特点构造方法常用方法使用示例注意事项 ConcurrentLinkedDeque ConcurrentLinkedDeque 是 Java 并发工具包(java.util.concurrent 包)中的一个线程安全的双端队列(Deque)实现,实现了 Deque 接口。它使用了链表结构,并且针对高并发环境进行了优化,非常适合

Docker 容器技术:简化 MySQL 主从复制部署与优化

Docker 容器技术:简化 MySQL 主从复制部署与优化 引言 随着大数据和云计算的快速发展,数据库的高可用性、可扩展性和易维护性成为了企业IT架构中的重要考量因素。MySQL 作为一款流行的开源数据库管理系统,其主从复制(Master-Slave Replication)功能为实现数据备份、故障恢复、读取扩展和数据分析提供了强有力的支持。然而,传统的 MySQL 主从复制部署过程复杂且容

Docker进入容器并运行命令

在讨论如何使用Docker进入容器并运行命令时,我们需要先理解Docker的基本概念以及容器的工作原理。Docker是一个开放平台,用于开发、交付和运行应用程序。它使用容器来打包、分发和运行应用程序,这些容器是轻量级的、可移植的、自包含的,能够在几乎任何地方以相同的方式运行。 进入Docker容器的几种方式 1. 使用docker exec命令 docker exec命令是最常用的进入正在运

Qt-常用控件(3)-多元素控件、容器类控件和布局管理器

1. 多元素控件 Qt 中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例. QTableView 是基于 MVC 设计的控件.QTableView 自身不持有数据,使用 QTab

spring ioc容器的原理

1. IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。 图1:软件系统中耦合的对象 如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协