C++STL中map和set的使用

1.认识KV结构

    KV 结构(Key-Value 结构)是一种简单而高效的数据存储和组织方式,核心思想是通过 "键(Key)" 与 "值(Value)" 的对应关系来管理数据。

基本概念

  • 键(Key):唯一的标识符,相当于数据的 "名字" 或 "索引",用于快速查找对应的值
  • 值(Value):实际存储的数据,可以是简单类型(如数字、字符串)或复杂类型(如对象、列表)

特点

  1. 简单直观:类似现实中的 "字典" 或 "通讯录",通过名字找内容
  2. 快速查询:通常基于哈希表实现,查找效率高(时间复杂度接近 O (1))
  3. 灵活性强:值可以是任意类型,不需要固定的数据结构
  4. 无固定 schema:不需要预先定义数据结构,可动态添加键值对

通俗易懂的解释:

KV 结构其实就是 “键值对” 结构,你可以把它想象成现实生活中的 “字典” 或 “通讯录”:

  • 键(Key) 就像字典里的 “词语” 或通讯录里的 “名字”,是唯一的标识
  • 值(Value) 就像字典里的 “解释” 或通讯录里的 “电话号码”,是对应的数据

比如:

  • 手机通讯录里,"张三" 是键,"138xxxx1234" 是值
  • 字典里,"苹果" 是键,"一种水果..." 是值
  • 你的个人信息中,"年龄" 是键,"25" 是值

这种结构的好处是:

  1. 找东西快,直接通过 “键” 就能定位到 “值”,不用从头到尾翻
  2. 灵活,想存什么就存什么,不需要固定格式
  3. 简单,一看就懂,就像查字典一样自然

2.序列式容器和关联式容器

序列式容器:

  • 像排队,数据按插入顺序排列,靠位置(比如下标)访问,允许重复。比如数组、链表。
  • 数据按 "线性顺序" 排列,就像一条直线上的珠子,每个元素有明确的前后位置关系。元素的位置仅由插入顺序决定,和元素本身的值无关。
  • 因为逻辑结构为线性序列的数据结构,两个位置存储的值之间一般没有紧密的关联关系,两个值交换位置,他依旧是序列式容器。

关联式容器:

  • 像字典,数据以 “键 - 值” 形式存,靠唯一的 “键” 直接查找,键一般不重复。比如 Map、Set。
  • 从逻辑结构来看:数据按 "键 - 值关联" 关系组织,更像一张对照表。元素的位置由 "键" 决定(通常通过哈希或排序规则),和插入顺序无关。查找时不需要关心位置,直接通过 "键" 就能定位到对应 "值",就像查字典时用单词(键)找解释(值),不用管这个单词在字典的第几页。
  • 关联容器中元素的位置是通过“键”值确定的,如果交换两个元素的位置,原有结构就被破坏了,就像平衡二叉树,在插入时就已经确定位置关系,这些元素共同组成了一个稳定的整体,如果改变了一个元素的位置,原有结构被破坏,不再是平衡树。

前置知识stl----pair

  • 成员类型
    • first_type:第一个模板参数 T1 的类型,即 pair 中第一个成员的类型。
    • second_type:第二个模板参数 T2 的类型,即 pair 中第二个成员的类型。
  • 成员变量
    • T1 first;:存储第一个值的成员变量。
    • T2 second;:存储第二个值的成员变量。
#include <iostream>
#include <utility>

int main() {
    // 创建一个 pair 对象,第一个元素是 int 类型,第二个是 string 类型
    std::pair<int, std::string> myPair(10, "Hello");

    // 访问 pair 的成员
    std::cout << "First: " << myPair.first << std::endl;
    std::cout << "Second: " << myPair.second << std::endl;

    return 0;
}

构造函数

(1)默认构造

成员变量为默认值

(2)拷贝构造和移动构造

(3)pair (const first_type& a, const second_type& b);

通过分别提供第一个元素和第二个元素的值来初始化 pair 对象。

#include <iostream>
#include <utility>
int main() {
    std::pair<int, double> p(1, 2.5);
    std::cout << p.first << " " << p.second << std::endl;
    return 0;
}

可以通过初始化列表的方式,初始化对象,也最常用

	pair<int, int> p2{ 1,2 };

make_pair

在构造pair对象时可以通过make_pair函数构造对象。

pair<int,double> p1(make_pair(1, 2.5));
std::cout << p1.first << " " << p1.second << std::endl;

3.set系列的使用

3.1set简单介绍

C++ STL 中的 set 是一种关联式容器

  1. 存储唯一元素:里面的元素不允许重复,每个值都是唯一的
  2. 自动排序:元素会按照默认(升序)或自定义的规则自动排序
  3. 基于键访问set 中元素本身就是 "键",通过元素值直接查找,无需索引
  4. 底层实现:通常用红黑树(一种平衡二叉搜索树)实现,查找、插入、删除效率高(时间复杂度 O (log n))

适合场景:需要存储不重复元素,且经常需要查找(判断一个元素是否存在)、排序的场景(如去重、集合运算等)。

set和map底层使用红黑树(kv结构)实现

3.2set常用接口介绍

1.模板参数

  • class T:这是 set 容器中存储元素的数据类型。例如,如果你想要一个存储整数的 set,那么 T 就会被实例化为 intset::key_type 和 set::value_type 都会是这个 T 类型,因为在 set 中,元素本身既作为键(key)也作为值(value)。
  • class Compare = less<T>:这是一个用于比较 set 中元素的函数对象类型。默认情况下,使用 less<T>,它会按照元素的升序来排列 set 中的元素。你也可以自定义一个比较函数对象来改变 set 中元素的排序规则(模板参数如果为大于关系,大的在左子树,小的在右子树)。
  • class Alloc = allocator<T>:这是用于内存分配的分配器类型。默认情况下,使用 allocator<T>,它负责 set 容器的内存分配和释放。

2.成员变量,迭代器类型

成员变量只有一种类型T

迭代器为双向迭代器,不能使用算法库中的sort排序

3.构造函数

1.explicit set (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());

  • 作用:这是 std::set 的默认构造函数,用于创建一个空的 set 容器。
  • 参数
    • comp:用于比较 set 中元素的函数对象,默认是 key_compare()(通常是 std::less<T>)。
    • alloc:内存分配器,默认是 allocator_type()(通常是 std::allocator<T>)。
  • explicit 关键字:它防止了隐式类型转换,即不能通过单个参数来隐式地构造一个 set 对象。

2.explicit set (const allocator_type& alloc);

  • 作用:这是一个只接受内存分配器参数的构造函数,同样用于创建一个空的 set 容器,但可以指定自定义的内存分配器。
  • 参数alloc 是自定义的内存分配器。

3.template <class InputIterator> set (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& = allocator_type());

  • 作用:这是一个范围构造函数,用于从指定的输入迭代器范围 [first, last) 中复制元素来初始化 set 容器。
  • 参数
    • first 和 last:定义了要复制元素的范围的起始和结束迭代器。
    • comp:比较函数对象,默认是 key_compare()
    • alloc:内存分配器,默认是 allocator_type()

4.set (const set& x);

  • 作用:这是拷贝构造函数,用于创建一个新的 set 容器,其内容是另一个 set 容器 x 的拷贝。

5.set (const set& x, const allocator_type& alloc);

  • 作用:这是带内存分配器的拷贝构造函数,用于创建一个新的 set 容器,其内容是另一个 set 容器 x 的拷贝,并且使用指定的内存分配器 alloc

6.set (set&& x);

  • 作用:这是移动构造函数,用于从另一个 set 容器 x 中 “移动” 资源来创建新的 set 容器,它可以避免不必要的数据拷贝,提高性能。

7.set (initializer_list<value_type> il, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());

  • 作用:这是使用初始化列表来构造 set 容器的构造函数,它可以方便地用花括号 {} 包围的元素列表来初始化 set
  • 参数
    • il:初始化列表,包含了要插入到 set 中的元素。
    • comp:比较函数对象,默认是 key_compare()
    • alloc:内存分配器,默认是 allocator_type()

4.operator=

1.set& operator= (const set& x);

  • 作用:这是拷贝赋值运算符,用于将另一个 set 容器 x 的内容拷贝到当前 set 容器中,替换当前 set 容器的内容。
#include <iostream>
#include <set>

int main() {
    std::set<int> set1 = {1, 2, 3};
    std::set<int> set2;

    // 使用拷贝赋值运算符
    set2 = set1;

    // 输出 set2 的内容
    for (int num : set2) {
        std::cout << num << " ";
    }
    // 输出:1 2 3

    return 0;
}

2.set& operator= (set&& x);

  • 作用:这是移动赋值运算符,用于将另一个 set 容器 x 的内容 “移动” 到当前 set 容器中,而不是进行拷贝。这可以提高性能,因为它避免了不必要的数据拷贝,之后 x 将不再拥有原来的数据。

3.set& operator= (initializer_list<value_type> il);

  • 作用:这是使用初始化列表进行赋值的运算符重载,用于将初始化列表 il 中的元素赋值给当前 set 容器,替换当前 set 容器的内容。
#include <iostream>
#include <set>
#include <initializer_list>

int main() {
    std::set<int> set1;

    // 使用初始化列表赋值
    set1 = {10, 20, 30};

    // 输出 set1 的内容
    for (int num : set1) {
        std::cout << num << " ";
    }
    // 输出:10 20 30

    return 0;
}

5.迭代器

6.容量相关函数

1.empty()

  • 作用:用于测试容器是否为空。如果容器中没有元素,返回 true;否则返回 false

2.size()

  • 作用:返回容器中当前元素的数量。

3.max_size()

  • 作用:返回容器理论上可以容纳的最大元素数量,这取决于系统和库的实现。

7.insert()

(1)pair<iterator, bool> insert (const value_type& val); 和 pair<iterator, bool> insert (value_type&& val);

  • 作用:插入一个值为 val 的元素到容器中。返回一个 pair,其中 first 是指向插入位置的迭代器,second 是一个布尔值,表示插入是否成功(如果容器中已存在该元素,则插入失败,second 为 false;否则为 true)。
#include <iostream>
#include <set>
int main() {
    std::set<int> s;
    auto result = s.insert(5);
    std::cout << "Insert successful: " << (result.second ? "Yes" : "No") << std::endl;
    return 0;
}

(2)iterator insert (const_iterator position, const value_type& val);和iterator insert (const_iterator position, value_type&& val);

  • 作用:在指定的位置 position 附近插入值为 val 的元素。返回一个指向插入元素的迭代器。

该接口使用频率很低

(3)通过一段迭代器区间初始化

#include <iostream>
#include <set>
#include <vector>
int main() {
    std::set<int> s;
    std::vector<int> vec = {1, 2, 3};
    s.insert(vec.begin(), vec.end());
    for (const auto& num : s) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

(4)通过初始化列表

#include <iostream>
#include <set>
int main() {
    std::set<int> s;
    s.insert({1, 2, 3});
    for (const auto& num : s) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

8.erase

(1)删除一个迭代器位置,通常与find配合使用,返回值为指向被删除元素的下一个元素的迭代器

(2)删除某个值,常用

(3)删除一段迭代器区间

9.swap,clear

swap:

std::set::swap 成员函数用于交换两个 std::set 容器的内容。即交换当前 std::set 对象和参数 x 所指向的 std::set 对象的元素。

几乎用不上

clear:

std::set::clear 成员函数用于清空 std::set 容器中的所有元素,使其大小变为 0

10.find与count

find:

  1. 作用find 成员函数用于在容器中查找指定的键。如果找到,返回指向该键的迭代器;如果未找到,返回指向容器末尾的迭代器(即 end())。
#include <iostream>
#include <set>
int main() {
    std::set<int> s = {1, 2, 3, 4, 5};
    auto it = s.find(3);
    if (it != s.end()) {
        std::cout << "Found: " << *it << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }
    return 0;
}

count:

  1. 作用count 成员函数用于统计容器中指定键的出现次数。对于 std::set 和 std::map(键唯一),返回值只能是 0 或 1
#include <iostream>
#include <set>
int main() {
    std::set<int> s = {1, 2, 3, 4, 5};
    size_t count = s.count(3);
    std::cout << "Count of 3: " << count << std::endl;
    return 0;
}

11.lower_bound与upper_bound

lower_bound:

  1. 作用lower_bound 成员函数返回一个迭代器,指向容器中第一个不小于(即大于或等于)指定键的元素。
#include <iostream>
#include <set>
int main() {
    std::set<int> s = {1, 3, 5, 7, 9};
    auto it = s.lower_bound(5);
    std::cout << *it << std::endl;
    return 0;
}

这里在 std::set<int> 中查找第一个不小于 5 的元素,找到了 5,所以返回的迭代器指向 5

upper_bound:

  1. 作用upper_bound 成员函数返回一个迭代器,指向容器中第一个大于指定键的元素。
#include <iostream>
#include <set>
int main() {
    std::set<int> s = {1, 3, 5, 7, 9};
    auto it = s.upper_bound(5);
    std::cout << *it << std::endl;
    return 0;
}

这里在 std::set<int> 中查找第一个大于 5 的元素,找到了 7,所以返回的迭代器指向 7

总结:这两个接口通常和erase的删除迭代器区间配合使用。

4.set与multiset差异

    在 C++ 标准库中,std::set 和 std::multiset 都是基于红黑树实现的关联容器,它们都能对元素进行自动排序 。但它们在元素唯一性、插入删除操作返回值以及应用场景等方面存在差别

元素唯一性

  • std::set:要求元素唯一,不允许容器中有重复的元素。当插入已经存在的元素时,插入操作会失败,容器的大小不会改变。
  • std::multiset:允许元素重复,插入相同元素时,容器会增加该元素的数量。
#include <iostream>
#include <set>
int main() {
    std::multiset<int> myMultiSet;
    myMultiSet.insert(1);
    myMultiSet.insert(2);
    auto result = myMultiSet.insert(2);
    std::cout << "Insert result: Success" << std::endl; 
    std::cout << "Multiset size: " << myMultiSet.size() << std::endl; 
    return 0;
}

插入删除操作返回值

  • std::setinsert 操作返回一个 std::pair,其中 first 是一个迭代器,指向插入的元素(如果插入成功)或者已经存在的元素;second 是一个 bool 值,表示插入是否成功。erase 函数删除指定元素,返回 void
  • std::multisetinsert 操作返回一个迭代器,指向新插入的元素 。erase 函数如果传入单个值作为参数,返回值是被删除元素的个数;如果传入迭代器作为参数,返回 void。
#include <iostream>
#include <set>
int main() {
    std::multiset<int> myMultiSet;
    myMultiSet.insert(2);
    myMultiSet.insert(2);
    size_t erasedCount = myMultiSet.erase(2);
    std::cout << "Number of elements erased: " << erasedCount << std::endl; 
    return 0;
}

输出为 Number of elements erased: 2 ,表示删除了两个值为 2 的元素。

std::multiset:适用于需要统计元素出现次数,或者允许元素重复出现的场景,比如统计一个班级中不同分数的学生人数(分数允许重复),或者统计文本中每个单词出现的次数等。

5.map系列的使用

在 C++ 的标准模板库(STL)中,std::map是一种关联容器,它以键值对(key-value pairs)的形式存储数据,基于红黑树实现

特性

  • 键值对存储:每个元素都是一个键值对,键(key)用于唯一标识元素,值(value)是与键相关联的数据。比如,用学生学号作为键,学生成绩作为值来构建一个map 。
  • 自动排序std::map中的元素会根据键的大小自动排序,默认使用std::less<Key>作为比较函数(Key是键的类型)。例如,当键为整数时,元素会按照升序排列。
  • 键的唯一性map中的键必须是唯一的,不允许出现重复的键。如果插入一个已存在的键,会覆盖该键对应的旧值。

map常用接口介绍

1.模板参数

模板参数

  1. class Key:键的类型。在 std::map 中,键是唯一的,用于标识元素。
  2. class T:值的类型。与键相关联的数据类型。
  3. class Compare = less<Key>:比较函数对象的类型,用于确定键的排序顺序。默认情况下,使用 std::less<Key>,即按照键的升序排列。
  4. class Alloc = allocator<pair<const Key, T>>:分配器类型,用于分配和释放内存。默认情况下,使用 std::allocator<pair<const Key, T>>
#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap;
    myMap[1] = "One";
    myMap[2] = "Two";
    myMap[3] = "Three";
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}

kv结构及双向迭代器

2.构造函数

1.explicit map (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());

  • 作用:默认构造函数,创建一个空的 std::map 对象。可以指定比较函数 comp 和分配器 alloc

2.explicit map (const allocator_type& alloc);

  • 作用:仅指定分配器的构造函数,创建一个空的 std::map 对象,并使用指定的分配器 alloc

3.template <class InputIterator> map (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& = allocator_type());

  • 作用:范围构造函数,使用范围 [first, last) 内的元素初始化 std::map 对象。可以指定比较函数 comp 和分配器 alloc
#include <iostream>
#include <map>
#include <vector>
int main() {
    std::vector<std::pair<int, std::string>> vec = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    std::map<int, std::string> myMap(vec.begin(), vec.end());
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}
  • 解释:这里使用 std::vector 中的元素范围 [vec.begin(), vec.end()) 初始化 std::map<int, std::string> 对象 myMap,然后遍历输出所有元素。

4.map (const map& x);

  • 作用:复制构造函数,使用另一个 std::map 对象 x 初始化当前 std::map 对象。
#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> originalMap;
    originalMap[1] = "One";
    originalMap[2] = "Two";
    std::map<int, std::string> myMap(originalMap);
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}

5.map (initializer_list<value_type> il, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());

  • 作用:初始化列表构造函数,使用初始化列表 il 中的元素初始化 std::map 对象。可以指定比较函数 comp 和分配器 alloc
#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}

3.operator=

(1)作用:复制赋值运算符,将另一个 std::map 对象 x 的内容复制到当前 std::map 对象中。

#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> originalMap;
    originalMap[1] = "One";
    originalMap[2] = "Two";
    std::map<int, std::string> myMap;
    myMap = originalMap;
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}

(3)作用:初始化列表赋值运算符,将初始化列表 il 中的元素赋值给当前 std::map 对象

#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap;
    myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}

4.迭代器

可对迭代器进行->first或->second等操作,获取迭代器位置的kv值

5.容量相关容器

用法与set相同

6.insert

(1) 部分

  1. pair<iterator, bool> insert (const value_type& val);
    • 作用:插入一个值为 val 的元素到容器中。返回一个 pair,其中 first 是指向插入位置的迭代器,second 是一个布尔值,表示插入是否成功(如果容器中已存在该元素,则插入失败,second 为 false;否则为 true)。
#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap;
    auto result = myMap.insert({1, "One"});
    std::cout << "Insert successful: " << (result.second ? "Yes" : "No") << std::endl;
    return 0;
}
  • 这里向空的 std::map<int, std::string> 中插入 {1, "One"},插入成功,所以 result.second 为 true

(3) 部分

  1. template <class InputIterator> void insert (InputIterator first, InputIterator last);
    • 作用:插入范围 [first, last) 内的所有元素到容器中。
#include <iostream>
#include <map>
#include <vector>
int main() {
    std::map<int, std::string> myMap;
    std::vector<std::pair<int, std::string>> vec = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    myMap.insert(vec.begin(), vec.end());
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}
  • 解释:这里将 std::vector 中的元素插入到 std::map<int, std::string> 中,由于 std::map 会自动排序和去重(这里没有重复元素),所以输出为 1: One2: Two3: Three

initializer list (4) 部分

  1. void insert (initializer_list<value_type> il);
    • 作用:插入初始化列表 il 中的所有元素到容器中。
#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap;
    myMap.insert({{1, "One"}, {2, "Two"}, {3, "Three"}});
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}

7.erase

  1. 删除迭代器位置
  2. 删除k值
  3. 删除一段迭代器区间

8.operator[]

std::map::operator[] 是一个重载的运算符,用于访问 std::map 中指定键 k 对应的值。如果键 k 不存在于 std::map 中,它会自动插入一个新的键值对,其中键为 k,值为该类型的默认值(例如,对于 int 类型,默认值为 0;对于 std::string 类型,默认值为空字符串)。

如果键k存在该函数会返回该“键”对应的“值”的引用,用于修改“值”

#include <iostream>
#include <map>
#include <string>
int main() {
    std::map<int, std::string> myMap;
    myMap[1] = "One";
    myMap[2] = "Two";
    std::cout << myMap[1] << std::endl;
    std::cout << myMap[3] << std::endl; 
    return 0;
}

返回值:

9.find与count

查找键,返回键位置的迭代器

判断一个值是否存在容器中

10.lower_bound与upper_bound

用法与set类似

6.multimap和map的差异

multimap和map的使⽤基本完全类似,主要区别点在于multimap⽀持关键值key冗余,那么
insert/find/count/erase都围绕着⽀持关键值key冗余有所差异,这⾥跟set和multiset完全⼀样,⽐如find时,有多个key,返回中序第⼀个。其次就是multimap不⽀持[],因为⽀持key冗余,[]就只能⽀持插⼊了,不能⽀持修改。

元素唯一性

  • std::map:要求键必须唯一,不允许容器中存在重复的键。当插入一个已存在的键时,会覆盖该键原来对应的值 。
  • std::multimap:允许键重复,同一键可以对应多个不同的值。在插入操作时,即便插入与已存在键相同的键值对,也会成功插入,不会覆盖 。

#include <iostream>
#include <map>
int main() {
    std::multimap<int, std::string> myMultiMap;
    myMultiMap.insert({1, "Alice"});
    myMultiMap.insert({1, "Bob"}); 
    std::cout << "Size of multimap: " << myMultiMap.size() << std::endl; 
    return 0;
}

插入操作返回值

  • std::mapinsert 操作返回一个 std::pair,其中 first 是一个迭代器,指向插入的元素(如果插入成功)或者已经存在的元素;second 是一个 bool 值,表示插入是否成功。
  • std::multimapinsert 操作返回一个迭代器,指向新插入的元素。因为一定能插入成功(键可重复),所以不通过返回值表示插入是否成功 。
#include <iostream>
#include <map>
int main() {
    std::multimap<int, std::string> myMultiMap;
    auto it = myMultiMap.insert({1, "Alice"});
    std::cout << it->second << std::endl; 
    return 0;
}

查找与删除操作特性

  • std::map:使用 find 查找元素时,若找到返回指向该元素的迭代器,找不到返回 end() 迭代器;使用 erase 删除元素时,删除指定键的元素或指定迭代器指向的元素。由于键唯一,操作相对简单。
  • std::multimap:由于键可重复,使用 find 查找元素时,找到的是键值对中第一个具有指定键的元素的迭代器;删除操作若传入键作为参数,会删除所有具有该键的元素,返回被删除元素的数量;若传入迭代器作为参数,仅删除迭代器指向的元素。
#include <iostream>
#include <map>
int main() {
    std::multimap<int, std::string> myMultiMap;
    myMultiMap.insert({1, "Alice"});
    myMultiMap.insert({1, "Bob"}); 
    size_t erasedCount = myMultiMap.erase(1); 
    std::cout << "Number of elements erased: " << erasedCount << std::endl; 
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值