📅  最后修改于: 2023-12-03 15:20:54.367000             🧑  作者: Mango
unordered_multimap
是C++ STL中的一个关联容器,它将一组键和一组值配对存储。和std::map类似,但它允许多个元素具有相同的键。特别地,这些键值对没有固定的顺序,底层实现为哈希表,对于键的顺序没有要求。
一般用于需要快速(O(1))查找、插入和删除元素的场景。
可以用于统计单词出现的次数,将行号与每个单词对应起来,统计访问日志中IP的数量等等。
首先应该#include <unordered_multimap>头文件。
std::unordered_multimap<int, std::string> umap;
这样就声明了一个空的unordered_multimap对象umap,其中键为int类型,值为std::string类型。
umap.insert({1, "apple"});
umap.insert({2, "banana"});
umap.insert({3, "orange"});
插入方式和其他STL容器非常类似,使用insert()函数。
如果你想插入一组键值对,在C++11之前必须这样做:
std::pair<int, std::string> p(4, "watermelon");
umap.insert(p);
而在C++11及以后,你可以这样插入:
umap.insert(std::make_pair(4, "watermelon"));
还可以使用emplace()函数,它在插入元素时不需要使用std::pair模板。
umap.emplace(5, "pear");
unordered_multimap在查找元素时需要注意的是,由于内部实现为哈希表,它没有固定的数值顺序,即使你在插入时是按照顺序来的。
std::unordered_multimap<int, std::string>::iterator itr; // 迭代器
itr = umap.find(2); // 查找键为2的元素
if (itr != umap.end()) {
std::cout << "找到了,值为:" << itr->second << std::endl;
} else {
std::cout << "没找到" << std::endl;
}
在上述代码中, umap.find(2) 会返回一个指向键为2的元素的迭代器。如果找到了,则输出该元素的值,否则输出 "没找到"。
如果你想遍历整个unordered_multimap,可以使用迭代器:
for (auto itr = umap.begin(); itr != umap.end(); ++itr) {
std::cout << itr->first << ": " << itr->second << std:endl;
}
也可以用auto关键字:
for (auto& e : umap) {
std::cout << e.first << ": " << e.second << std::endl;
}
和其他STL容器一样,unordered_multimap也可以使用erase()函数删除元素。
umap.erase(2); // 删除键为2的元素
umap.erase(umap.begin()); // 删除第一个元素
umap.erase(umap.find(1), umap.end()); // 删除键为1的所有元素
#include <iostream>
#include <unordered_multimap>
#include <string>
int main() {
std::unordered_multimap<std::string, int> umap;
// 添加元素
umap.emplace("apple", 10);
umap.emplace("orange", 20);
umap.emplace("banana", 15);
umap.emplace("kiwi", 5);
umap.emplace("apple", 18);
umap.emplace("orange", 30);
// 查找元素
std::cout << "apple的值为:";
auto range = umap.equal_range("apple");
for (auto itr = range.first; itr != range.second; ++itr) {
std::cout << itr->second << " ";
}
std::cout << std::endl;
// 遍历
for (auto& e : umap) {
std::cout << e.first << ": " << e.second << std::endl;
}
// 删除元素
umap.erase("kiwi");
// 遍历
for (auto& e : umap) {
std::cout << e.first << ": " << e.second << std::endl;
}
return 0;
}
输出:
apple的值为:10 18
orange: 20
orange: 30
kiwi: 5
banana: 15
apple: 10
apple: 18
banana: 15
orange: 20
orange: 30
apple: 10
apple: 18
orange: 20
orange: 30
banana: 15
kiwi: 5
orange: 20
orange: 30
banana: 15
apple: 10
apple: 18
orange: 20
orange: 30
banana: 15
和其他关联容器(如map、multimap等),unordered_multimap的特点是允许多个元素具有相同的键。和vector、deque、list、forward_list等其他STL容器不同的是,unordered_multimap不是线性容器,而是哈希容器。因此,它的性能特点也不同,无法在数组或链表上保证O(1)的操作。unordered_multimap的查找、插入和删除操作的复杂度都是O(1),而其他容器的复杂度则是O(logN)。
unordered_multimap一般比其他STL关联容器速度更快,因为它使用哈希表来实现。但是,它的不同点也带来了一些问题,如它的元素没有固定的顺序;哈希容器不是线性容器,所以迭代器的增加不一定是连续的;哈希表会浪费一些空间用于存储散列表,所以unordered_multimap的内存占用比其他STL关联容器稍大。
unordered_multimap是STL中一种基于哈希表实现的关联容器,允许多个元素具有相同的键。它适用于需要快速查找、插入和删除元素的场景,如统计单词出现的次数、将行号与每个单词对应起来、统计访问日志中IP的数量等等。unordered_multimap与其他STL容器相比,具有更快的速度和更低的复杂度。但它也有一些缺点,如元素没有固定的顺序、迭代器的增加不一定是连续的、内存占用比其他STL关联容器稍大等。
参考资料:
官方文档:https://en.cppreference.com/w/cpp/container/unordered_multimap