C++ Multiset

2025年6月6日 | 阅读 11 分钟

在 C++ 中,multiset 是 STL(标准模板库) 的一个重要组成部分。Multiset 是类似于 set 的关联容器,用于存储已排序的值(值本身就是类型 T 的键)。与存储唯一键的 Set 不同,Multiset 可以包含重复的键。默认情况下,它使用 < 运算符来比较多个键。Multiset 中的元素值可以插入或删除,但不能修改。

语法

它具有以下语法:

在这个语法中,

  • T: 代表 multiset 容器中存储的元素类型。
  • Compare: 代表一个比较类,它接受两个相同类型的参数,返回一个 bool 值。此参数是可选的,默认为二元谓词。
  • Alloc: 代表用于定义存储分配模型的分配器对象的类型。

声明和初始化

C++ 中,我们可以用多种不同的方式初始化和声明 multiset,如下例所示:

示例

编译并运行

输出

Multiset elements: 10 10 20 20 30 40

说明

在此示例中,我们包含了所需的头文件,并创建了一个整数 multiset,该 multiset 已用一些重复值进行了初始化。之后,multiset 默认按顺序存储元素,并且也允许重复。 the for 循环 遍历 multiset 并打印所有元素,显示为升序。

C++ Multiset 的基本操作

可以在 multiset 上执行多种操作。其中一些如下:

插入元素

在 C++ 中,我们可以使用 insert() 方法 在 multiset 中插入元素。Multiset 会自动按照添加的顺序维护元素。

语法

它具有以下语法:

C++ Multiset 插入元素的示例

让我们以一个例子来说明如何在 C++ 中向 multiset 插入元素。

示例

编译并运行

输出

Multiset elements: 10 10 20 30

说明

在此示例中,在 main() 函数中声明了一个 multiset<int> 类型的 number。使用 insert() 函数插入了元素 10、20、10 和 30。由于 multiset 允许重复并保持元素排序,输出将以升序打印元素,其中包括重复的 10。之后,for 循环迭代 multiset 并打印其每个值。

访问元素

在 multiset 中,我们需要通过迭代器按位置访问元素。例如,如果我们想获取第 3 个元素,我们需要将 begin() 迭代器向前移动两个位置(通过递增)。我们还可以使用 next() 或 advance() 函数来代替递增或递减。

C++ Multiset 访问元素的示例

让我们以一个例子来说明如何在 C++ 中访问 multiset 中的元素。

示例

编译并运行

输出

Multiset elements: 10 10 20 30 40

说明

在此示例中,我们使用值 {40, 10, 30, 20, 10} 初始化了一个 multiset<int>。由于 multiset 按排序顺序存储元素并允许重复,因此元素会自动排列。之后,一个带有迭代器的 for 循环从 multiset 的开头到结尾,使用 *it 打印每个值。

查找元素

在 C++ 中,multiset 通过 find() 成员函数支持快速按值查找操作。如果找到元素,find() 函数将返回指向该元素的迭代器;否则,它将返回 end() 迭代器。

语法

它具有以下语法:

在这里,我们可以通过使用 begin() 和 end() 迭代器轻松访问第一个和最后一个元素。

C++ Multiset 查找元素的示例

让我们以一个例子来说明如何在 C++ 中查找 multiset 中的元素。

示例

编译并运行

输出

Element 20 found in the multiset.

说明

在此示例中,我们创建了一个包含一些整数的 multiset,并尝试使用 find() 方法查找值 20。如果找到元素,它将打印一条消息,指出元素已找到;否则,未找到。因为 multiset 支持重复,所以 find() 函数将返回指向该值某个出现次数的迭代器。

遍历元素

在 C++ 中,遍历与其他容器类似,multiset 可以通过使用基于范围的 for 循环或使用 begin() 和 end() 迭代器进行高效迭代。为了遍历具有相同键的所有元素,请使用 equal_range() 函数 返回的范围,而不是 begin() 和 end()。

C++ 遍历元素的示例

让我们举一个例子来演示如何在 C++ 中遍历元素。

示例

编译并运行

输出

Multiset elements: 10 20 30 40 50

说明

在此示例中,由于 multiset 按排序顺序存储元素,因此它们会自动排列为 {10, 20, 30, 40, 50}。之后,一个带有迭代器的 for 循环 从 begin() 到 end(),通过解引用每个迭代器来访问和打印值。

删除元素

如果我们想从 multiset 中删除元素,我们可以使用 erase() 函数。它可以提供值或迭代器来调用。但是,如果提供了值,它会删除该值的所有实例。

C++ 删除元素的示例

让我们以一个例子来说明如何在 C++ multiset 中删除元素。

示例

编译并运行

输出

Multiset after deletion: 10 20 40 

说明

在此示例中,我们创建了一个包含重复项的整数 multiset。它使用 find() 和 erase(it) 删除两个 20 中的一个,并使用 erase(30) 删除所有 30。最后,它以升序打印剩余的元素。

将 Multiset 按降序排序

如果我们想按降序获取 multiset 元素,我们可以修改以下语法:

C++ Multiset 按降序排序的示例

让我们以一个例子来说明如何在 C++ 中将 multiset 按降序排序。

示例

编译并运行

输出

Multiset in descending order: 40 30 20 20 10

说明

在此示例中,我们创建了一个带有自定义比较器 greater<int> 的 multiset,它按降序存储元素。它使用一些值初始化 multiset,并使用基于范围的循环打印它们。之后,输出将显示从高到低的排序元素。

使用 swap() 交换 Multiset

在 C++ 中,交换两个 multiset 容器可以有效地交换它们的内容。 the swap() 函数 通过交换内部指针以恒定时间运行。

C++ 使用 Swap() 函数交换 Multiset 的示例

让我们以一个例子来说明如何在 C++ 中使用 swap() 函数交换 multiset。

示例

编译并运行

输出

Before swap:
Set1: 10 20 30 
Set2: 40 50 

After swap:
Set1: 40 50 
Set2: 10 20 30 

说明

在此示例中,我们初始化了两个具有不同值的 multiset,打印了它们,然后使用 swap() 交换了它们。交换后,它们再次打印出来,以证明它们的内容已被交换。

C++ Multiset empty() 和 size() 方法

在 C++ 中,我们可以使用容量方法 empty()size() 来检查 multiset 是否为空以及它的大小。

empty() 方法返回 1 和 0 值。

  • 1 (true) - 如果 multiset 为空
  • 0 (false) - 如果 multiset 不为空

C++ Multiset empty() 和 size() 方法使用示例

让我们以一个例子来说明如何在 C++ 中使用 empty() 和 size() 函数来使用 multiset。

示例

编译并运行

输出

Multiset contents before clear: 5 15 15 25 35 35 35 
Is multiset empty? No
Multiset size: 7

Multiset contents after clear: 
Is multiset empty? Yes
Multiset size: 0

说明

在此示例中,我们创建了一个包含一些重复值的 multiset,打印其内容,检查并显示它是否为空以及其大小,并使用 clear() 清除所有元素。清除后,它再次打印 multiset 并再次检查 empty() 和 size() 以验证它现在为空。

成员函数

以下是 multiset 所有成员函数的列表

构造函数/析构函数

下表显示了 C++ Multiset 中使用的几个构造函数/析构函数。

函数描述
(构造函数)构造 multiset
(析构函数)Multiset 析构函数
operator=将 multiset 的元素复制到另一个 multiset。

迭代器

下表显示了 C++ Multiset 中使用的几个迭代器函数。

函数描述
Begin返回指向 multiset 中第一个元素的迭代器。
Cbegin返回指向 multiset 中第一个元素的 const 迭代器。
End返回指向 past-end 的迭代器。
cend返回指向 past-end 的 const 迭代器。
rbegin返回指向末尾的反向迭代器。
rend返回指向开头的反向迭代器。
crbegin返回指向末尾的 const 反向迭代器。
crend返回指向开头的 const 反向迭代器。

容量

下表显示了 C++ Multiset 中使用的几个容量函数。

函数描述
empty如果 multiset 为空,则返回 true。
大小返回 multiset 中的元素数量。
max_size返回 multiset 的最大大小。

修饰符

下表显示了 C++ Multiset 中使用的几个修改器函数。

函数描述
insert在 multiset 中插入元素。
erase从 multiset 中删除元素。
swap交换 multiset 的内容。
clear删除 multiset 中的所有元素。
emplace构造并向 multiset 中插入新元素。
emplace_hint通过提示构造并向 multiset 中插入新元素。

观察器

下表显示了 C++ Multiset 中使用的几个修改器函数。

函数描述
key_comp返回键比较对象的副本。
value_comp返回值比较对象的副本。

操作

下表显示了 C++ Multiset 中使用的几个操作。

函数描述
find搜索具有给定键的元素。
count获取与给定键匹配的元素数量。
lower_bound返回指向下界的迭代器。
upper_bound返回指向上界的迭代器。
equal_range返回与给定键匹配的元素范围。

分配器

下表显示了 C++ Multiset 中使用的几个分配函数。

函数描述
get_allocator返回用于构造 multiset 的分配器对象。

非成员重载函数

下表显示了 C++ Multiset 中使用的几个非成员重载函数。

函数描述
operator==检查两个 multiset 是否相等。
operator!=检查两个 multiset 是否相等。
operator<检查第一个 multiset 是否小于另一个。
operator<=检查第一个 multiset 是否小于或等于另一个。
operator>检查第一个 multiset 是否大于另一个。
operator>=检查第一个 multiset 是否大于或等于另一个。
swap()交换两个 multiset 的元素。

结论

总之,C++ STL 包含 multisets。Multisets 是已排序的 Set 容器,用于存储已排序的值(值是类型 T 的键)。与 C++ sets 不同,multisets 可以包含不同的冗余键。Multiset 默认允许我们使用运算符比较键。multiset 的项的值可以插入或删除,但不能修改。

C++ STL Multiset 选择题

1) 关于 C++ 中的 multiset,以下哪项是正确的?

  1. 它只存储唯一元素
  2. 它存储未排序的值
  3. 它允许重复值
  4. 它不支持迭代器
 

答案: c) 它允许重复值


2) 以下哪个函数用于在 multiset 中查找元素?

  1. search()
  2. contains()
  3. locate()
  4. find()
 

答案: d) find()


3) erase(value) 在 multiset 中做什么?

  1. 仅删除该值的一个实例
  2. 删除该值的所有实例
  3. 如果存在重复项,则抛出错误
  4. 删除最小的实例
 

答案: b) 删除该值的所有实例


4) 关于 multiset 中的元素修改,以下哪个陈述是正确的?

  1. 元素插入后不能修改
  2. 可以使用迭代器直接修改元素
  3. 可以使用 set() 函数修改元素
  4. 可以通过索引访问和修改元素
 

答案: a) 元素插入后不能修改


5) 如果我们在 C++ 中对两个 multiset 使用 swap() 函数会发生什么?

  1. 只保留唯一值
  2. 值将被合并
  3. 内容将被交换
  4. 什么也不会发生
 

答案: c) 内容将被交换


下一个主题C++ multiset