文章目录
- map (映射)
-
-
- 定义
-
- map构造和赋值
-
- map大小和交换
-
- map插入和删除
-
- map查找和统计
-
- map容器排序
- multimap 容器 (多重映射)
-
map (映射)
定义
C++中的map是一种关联容器,它提供了一种键-值(key-value)对的存储方式。map容器中的元素是按照键的顺序进行排序的,并且每个键都唯一。通过使用键来访问其相应的值,我们可以在O(log n)的时间复杂度内进行快速的查找、插入和删除操作。
map与set类似,但不同之处在于map存储的是键值对(key-value pair),而set只存储单个元素。每个键值对在map中被视为一个元素,由键(key)和值(value)组成。键用于唯一标识元素,值则是与键相关联的数据。
注意
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
map
是一个有序容器,所有元素都会根据元素的键值自动排序
- 每个键只能在
map
中唯一出现。如果插入一个已存在的键,那么新的值会取代旧的值。
优点
- 快速查找
map基于红黑树实现,这使得在大量数据情况下,查找操作具有较好的时间复杂度(平均为O(log n))。因此,可以根据key值快速找到value值
- 有序性
map以键的顺序进行排序,这意味着通过map迭代器遍历时可以按照键的有序性进行操作。这对于需要按照键的顺序访问数据的场景非常方便。
- 唯一键
map中每个键都是唯一的,这意味着相同的键只会出现一次。当需要确保数据中的键是唯一的时,map提供了一种有效的数据结构来实现这一点。
- 稳定性
由于map基于红黑树实现,它对插入和删除操作的平均时间复杂度为O(log n),这使得在频繁更新数据的场景中也能保持较好的性能稳定性。
map构造和赋值
构造
map mp;
//map默认构造函数:
map(const map &mp);
//拷贝构造函数
赋值
map& operator=(const map &mp);
//重载等号操作符
示例
注意:map中所有元素都是成对出现,插入数据时候要使用对组
#include
#include
输出
1: apple
2: banana
3: orange
map大小和交换
函数原型
size();
//返回容器中元素的数目
empty();
//判断容器是否为空
swap(st);
//交换两个集合容器
示例
#include
#include
输出结果
Size: 3
Map is not empty
Map after swap:
4: grape
5: kiwi
分析
在上述示例中,我们首先创建了一个map,并插入了几个键值对。然后我们使用size()函数获取容器中元素的数目,并使用empty()函数判断容器是否为空。
接下来,我们创建了另一个map anotherMap,并插入了一些元素。然后使用swap()函数交换了两个map的内容,将原来的mp与anotherMap进行了交换。最后,我们遍历并输出了交换后的map的元素。
需要注意的是,swap()函数会直接交换两个map的内容,而不是创建副本或者复制元素。
map插入和删除
函数原型
insert(elem);
//在容器中插入元素。
clear();
//清除所有元素
erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);
//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(key);
//删除容器中值为key的元素。
四种插入方式
-
m.insert(pair(1, 10));
-
m.insert(make_pair(2, 20));
-
m.insert(map::value_type(3, 30));
-
m[4] = 40;
注意
map::value_type(3, 30)
是一个创建 map
中键值对的方法。它使用了 map
的嵌套类型 value_type
,表示键值对的类型。注意,map::value_type
是 pair
的别名,其中 Key
是键的类型,T
是值的类型。
value_type 是 map 类的内部类型,表示键值对的类型。在这里,map::value_type 表示 pair,即键为 const int 类型,值为 int 类型的键值对。
这种方式仅适用于 C++03 标准及之前的版本。从 C++11 标准开始,我们可以直接使用简化的插入语法,如 m.insert({3, 30})
示例
#include
#include
在上述示例中,我们首先创建了一个map,然后使用四种不同的插入方式向map中插入了一些元素,并使用printMap函数输出map的内容。
接下来,我们使用erase函数删除了第一个元素和键为3的元素,并再次使用printMap函数输出了更新后的map。
最后,我们使用clear函数清空了整个map,并再次使用printMap函数输出了清空后的map。
需要注意的是,map中的元素是按照键的顺序进行排序的,而且键必须是唯一的。同时,使用erase函数删除元素时可以指定要删除的元素的位置或者键值。
map查找和统计
函数原型
find(key);
//查找key是否存在,若存在,返回该键的元素的迭代器;否则返回set.end();
count(key);
//统计key的元素个数 (对于map,结果为0或者1, 最多一个不重复)
示例
#include
#include
输出
键为 3 的元素存在,值为 30
键为 4 的元素个数为 1
键为 5 的元素不存在
在上述示例中,我们首先创建了一个map并向其中插入了几个元素。然后,我们使用find(key)函数来查找键为 3 的元素,并根据返回的迭代器判断该元素是否存在。
接下来,我们使用count(key)函数统计键为 4 的元素的个数。
最后,我们使用find(key)函数查找一个不存在的键 5,并根据返回的迭代器判断该元素是否存在。
需要注意的是,对于count(key)函数来说,由于map容器的特性,它的返回值要么是 0(表示键不存在),要么是 1(表示键存在)。因为map 中每个键都是唯一的。
map容器排序
- map容器默认排序规则为 按照key值进行 从小到大排序
- 利用仿函数可以指定map容器的排序规则
- 对于自定义数据类型,map必须要指定排序规则,同set容器
重载 operator()
运算符是定义一个仿函数的必要条件。实际上,仿函数就是一个类对象,在使用仿函数时,我们可以像调用函数一样使用它进行计算。在 C++ 中,仿函数可以重载多个运算符,但重载 operator()
运算符是最常见的情况,因为它使得对象可以被像函数一样调用,并且提供了比较接近函数调用的语法。除了重载 operator()
运算符外,仿函数还可以根据需要重载其他运算符,例如 operator+
、operator-
等运算符,以实现特定的功能。
示例:
#include
#include
输出
4: Charlie
3: Alice
2: David
1: Bob
在上述示例中,我们定义了一个名为 MyComparator 的仿函数类,用于指定排序规则。该仿函数类重载了 operator() 运算符,其中通过返回 a > b 来实现从大到小排序。
然后,我们创建了一个类型为 map 的 map 容器,并将自定义的 MyComparator 类作为第三个模板参数传递给 map,以指定排序规则为从大到小。
接下来,我们向 map 中插入了几个元素,并通过遍历 map 打印出按照自定义排序规则排序后的结果。
需要注意的是,在使用自定义排序规则时,关键是要将该规则作为 map 的第三个模板参数进行指定,以告诉 map 使用自定义排序规则。
multimap 容器 (多重映射)
定义
multimap 是 C++ STL 中的一个关联容器,它提供了一种键值对的存储方式,允许一个键对应多个值。multimap 容器中的元素按照键的自然顺序进行排序,并且可以有重复的键。
特点
可以有重复的键。
键和值可以是任意数据类型。
键值对是按照键的自然顺序进行排序的。
提供了高效的插入、查找和删除操作
和map的区别
multimap 可以有多个相同的键,map不行,其他二者几乎一致
示例
#include
#include
int main() {
std::multimap<int, std::string> mm;
mm.insert(std::pair<int, std::string>(3, "Alice"));
mm.insert(std::pair<int, std::string>(1, "Bob"));
mm.insert(std::pair<int, std::string>(2, "Charlie"));
mm.insert(std::pair<int, std::string>(3, "David"));
for (const auto& pair : mm) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
输出
1: Bob
2: Charlie
3: Alice
3: David
在上述示例中,我们创建了一个 multimap 类型的 multimap 容器,并向其中插入了几个键值对。其中,键是 int 类型,值是 string 类型。
然后,我们通过遍历 multimap 容器,打印出所有的键值对。
需要注意的是,由于 multimap 容器允许有重复的键,因此在遍历时,可能会输出相同键的多个值。
![在这里插入图片描述](http://img.e-com-net.com/image/info8/515a42f8b5e54985a5d55a5af591bc40.gif)