C++基础知识(八:STL标准库 Map和multimap )

简介: C++ 标准模板库(STL)中的 map 容器是一种非常有用的关联容器,用于存储键值对(key-value pairs)。在 map 中,每个元素都由一个键和一个值组成,其中键是唯一的,而值则可以重复。

目录

Map

基本概念

声明和初始化

插入元素

访问元素

遍历 map

编辑

可能遇到的错误:

编辑

常用函数

多值映射 multimap

简单示例

常用函


Map

C++ 标准模板库(STL)中的 map 容器是一种非常有用的关联容器,用于存储键值对(key-value pairs)。在 map 中,每个元素都由一个键和一个值组成,其中键是唯一的,而值则可以重复。

基本概念

  • 键与值:键用于唯一标识一个元素,而值则是与键关联的数据。键和值通常以 std::pair 的形式存储,但在大多数操作中,你可以直接使用键和值。
  • 排序map 中的元素会根据键的比较进行排序。默认情况下,键按照升序排列,但可以通过提供自定义的比较函数或比较对象来改变排序方式。
  • 查找效率:由于 map 内部通常使用红黑树实现,查找、插入和删除操作的时间复杂度为 O(log N),其中 N 是容器中的元素数量。

声明和初始化

Cpp

#include <map>
#include <string>
#include <iostream>
// 声明一个 map,键为 int 类型,值为 std::string 类型
std::map<int, std::string> myMap;
// 初始化 map
std::map<int, std::string> myMap = {
    {1, "apple"},
    {2, "banana"},
    {3, "cherry"}
};

image.gif

插入元素

Cpp

myMap.insert({4, "date"}); // 使用 make_pair 或者直接初始化 pair
myMap[5] = "elderberry";   // 使用 [] 操作符,如果键不存在,会自动创建一个新的元素

image.gif

访问元素

Cpp

std::string fruit = myMap[3]; // 获取键为3的值
fruit = myMap.at(3);           // 与[]类似,但会抛出异常如果键不存在

image.gif

遍历 map

Cpp

for (const auto& element : myMap) {
    std::cout << element.first << ": " << element.second << std::endl;
}

image.gif

或者使用迭代器:

Cpp

for (auto it = myMap.begin(); it != myMap.end(); ++it) {
    std::cout << it->first << ": " << it->second << std::endl;
}

image.gif

image.gif 编辑

可能遇到的错误:

1。C++版本不够

image.gif 编辑

查看一下自己的版本

image.gif 编辑

我这个就是C++98,像auto这些都需要C++11以上的版本,升级版本大家可以自行搜索。

常用函数

  • find():查找键是否存在,返回指向键的迭代器或 end() 如果找不到。
  • count():返回键的数量,对于 map 总是返回 0 或 1。
  • erase():删除指定键的元素,可以接受键或迭代器作为参数。
  • empty():检查 map 是否为空。
  • size():返回 map 中的元素数量。
  • clear():删除 map 中的所有元素。

多值映射 multimap

multimap 是 C++ STL 中的一个关联容器,它类似于 map,但是它允许一个特定的键对应多个值。这意味着在 multimap 中,键可以不是唯一的,相同键的多个元素会被存储在一起,并且这些元素将根据它们的键按升序排序。

  1. 键值对存储multimap 存储键值对,其中键用于索引,值是与键相关联的数据。键和值分别定义为模板参数的类型。
  2. 键的非唯一性: 不同于 mapmultimap 允许有多个元素拥有相同的键。这意味着你可以存储多个与同一键关联的值。
  3. 自排序multimap 内部使用红黑树(一种自平衡的二叉搜索树)实现,这意味着元素会根据键的值自动排序。默认情况下,键按照升序排序,但你可以通过提供自定义的比较函数或比较对象来改变排序规则。
  4. 高效查找、插入和删除: 由于使用了红黑树结构,multimap 的查找、插入和删除操作的时间复杂度都是 O(log n),其中 n 是容器中的元素数。
  5. 迭代器稳定: 当使用 erase 函数删除一个元素时,不会影响其他元素的位置,因此指向未被删除元素的迭代器和引用仍然是有效的。
  6. 成员函数multimap 提供了一系列成员函数,如 inserterasefindcountequal_range 等,用于操作和查询容器。
  7. 大小和容量: 它提供了 sizeemptymax_size 成员函数,用于检查容器的当前大小、是否为空以及最大可能的大小。
  8. 迭代器和反向迭代器multimap 支持正向迭代器和反向迭代器,允许你遍历整个容器或反向遍历容器。
  9. 键值对的访问: 你可以使用 beginend 成员函数获得迭代器,然后通过迭代器访问键值对。multimap 不支持 operator[],因为键可能不是唯一的,但提供了 at 函数来访问键存在的元素,如果键不存在,at 将抛出 std::out_of_range 异常。

简单示例

#include <map>
#include <iostream>
using namespace std;
std::multimap<int, std::string> myMultimap;
int main(int argc, char const *argv[])
{
    myMultimap.insert(std::make_pair(1, "apple"));
    myMultimap.insert(std::make_pair(1, "orange"));
    auto it = myMultimap.find(1);
    auto range = myMultimap.equal_range(1);
  
  for (const auto &element : myMultimap)
    {
        std::cout << element.first << ": " << element.second << endl;
    }
  
  std::cout << "delete data" << std::endl;
  
    myMultimap.erase(myMultimap.begin()); // 删除第一个元素
    myMultimap.erase(1);                  // 删除所有键为1的元素
    for (const auto &element : myMultimap)
    {
        std::cout << element.first << ": " << element.second << endl;
    }
    return 0;
}

image.gif

image.gif 编辑

常用函数

  1. insert(const value_type& val)insert(value_type&& val): 向 multimap 插入一个元素。可以插入一个键值对,如果键已经存在,新值将被插入在现有相同键值对后面。
  2. insert(InputIterator first, InputIterator last): 插入从迭代器 firstlast 的一系列元素。
  3. insert(const_iterator hint, const value_type& val): 插入一个元素,并给出一个迭代器作为插入点的提示,但实际插入位置由键的顺序决定。
  4. erase(const key_type& k): 删除所有键为 k 的元素,返回被删除的元素数量。
  5. erase(iterator position): 删除由 position 指向的单个元素。
  6. erase(iterator first, iterator last): 删除由 [first, last) 范围内的所有元素。
  7. swap(multimap& x): 与另一个 multimap 交换内容。
  8. clear(): 清空 multimap,移除所有元素。
  9. find(const key_type& k): 返回指向第一个键为 k 的元素的迭代器,如果未找到则返回 end()
  10. count(const key_type& k): 返回键为 k 的元素数量。
  11. equal_range(const key_type& k): 返回键为 k 的所有元素的范围,返回一个包含两个迭代器的 std::pair,分别指向第一个和最后一个键为 k 的元素。
相关文章
|
2天前
|
C语言 C++ 开发者
C++基础知识(一:命名空间的各种使用方法)
C++在C的基础上引入了更多的元素,例如类,类的私密性要比C中的结构体更加优秀,引用,重载,命名空间,以及STL库,模板编程和更多的函数,在面向对象的编程上更加高效。C语言的优势则是更加底层,编译速度会更快,在编写内核时大多数都是C语言去写。 在C++中,命名空间(Namespace)是一种组织代码的方式,主要用于解决全局变量、函数或类的命名冲突问题。命名空间提供了一种封装机制,允许开发者将相关的类、函数、变量等放在一个逻辑上封闭的区域中,这样相同的名字在不同的命名空间中可以共存,而不会相互干扰。
|
2天前
|
C++
C++基础知识(二:引用和new delete)
引用是C++中的一种复合类型,它是某个已存在变量的别名,也就是说引用不是独立的实体,它只是为已存在的变量取了一个新名字。一旦引用被初始化为某个变量,就不能改变引用到另一个变量。引用的主要用途包括函数参数传递、操作符重载等,它可以避免复制大对象的开销,并且使得代码更加直观易读。
|
2天前
|
算法 编译器 C++
C++基础知识(三:哑元和内联函数和函数重载)
在C++编程中,"哑元"这个术语虽然不常用,但可以理解为在函数定义或调用中使用的没有实际功能、仅作为占位符的参数。这种做法多见于模板编程或者为了匹配函数签名等场景。例如,在实现某些通用算法时,可能需要一个特定数量的参数来满足编译器要求,即使在特定情况下某些参数并不参与计算,这些参数就可以被视为哑元。
|
2天前
|
C++
C++基础知识(四:类的学习)
类指的就是对同一类对象,把所有的属性都封装起来,你也可以把类看成一个高级版的结构体。
|
2天前
|
自然语言处理 程序员 C++
C++基础知识(五:运算符重载)
运算符重载是C++中的一项强大特性,它允许程序员为自定义类型(如类或结构体)重新定义标准运算符的行为,使得这些运算符能够适用于自定义类型的操作。这样做可以增强代码的可读性和表达力,使得代码更接近自然语言,同时保持了面向对象编程的封装性。
|
2天前
|
存储 编译器 C++
C++基础知识(六:继承)
多态是面向对象编程的四大基本原则之一,它让程序能够以统一的接口处理不同的对象类型,从而实现了接口与实现分离,提高了代码的灵活性和复用性。多态主要体现在两个层面:静态多态(编译时多态,如函数重载)和动态多态(运行时多态,主要通过虚函数实现)。
|
2天前
|
存储 编译器 C++
C++基础知识(七:多态)
多态是面向对象编程的四大基本原则之一,它让程序能够以统一的接口处理不同的对象类型,从而实现了接口与实现分离,提高了代码的灵活性和复用性。多态主要体现在两个层面:静态多态(编译时多态,如函数重载)和动态多态(运行时多态,主要通过虚函数实现)。
|
2天前
|
存储 算法 程序员
C++基础知识(八:STL标准库(Vectors和list))
C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), lists(链表), 和 stacks(栈)等. STL容器的提供是为了让开发者可以更高效率的去开发,同时我们应该也需要知道他们的底层实现,这样在出现错误的时候我们才知道一些原因,才可以更好的去解决问题。
|
2天前
|
算法 前端开发 C++
C++基础知识(八:STL标准库 deque )
deque在C++的STL(Standard Template Library)中是一个非常强大的容器,它的全称是“Double-Ended Queue”,即双端队列。deque结合了数组和链表的优点,提供了在两端进行高效插入和删除操作的能力,同时保持了随机访问的特性。

热门文章

最新文章