unordered_map是一个关联容器,用于存储由键值和映射值组合而成的元素。键值用于唯一标识元素,映射值是与键关联的内容。键和值都可以是任何预定义或用户定义的类型。简单来说,unordered_map就像一个字典类型的数据结构,它将元素存储在自身中。它包含连续的对 (key, value),允许根据其唯一键快速检索单个元素。
内部 unordered_map 使用哈希表实现,提供给 map 的键被哈希到哈希表的索引中,这就是为什么数据结构的性能在很大程度上取决于哈希函数,但平均而言,从哈希表中搜索、插入和删除的成本是 O(1)。
注意:在最坏的情况下,其时间复杂度可能会从 O(1) 变为 O(n),尤其是对于大素数。在这种情况下,强烈建议使用映射,以避免出现 TLE(超出时间限制)错误。
语法:
unordered_map 语法
下面是演示无序映射的 C++ 程序:
// C++ program to demonstrate
// functionality of unordered_map
#include <iostream>
#include <unordered_map>
using namespace std;
// Driver code
int main()
{
// Declaring umap to be of
// <string, int> type key
// will be of STRING type
// and mapped VALUE will
// be of int type
unordered_map<string, int> umap;
// inserting values by using [] operator
umap["GeeksforGeeks"] = 10;
umap["Practice"] = 20;
umap["Contribute"] = 30;
// Traversing an unordered map
for (auto x : umap)
cout << x.first << " " <<
x.second << endl;
}
输出
Contribute 30
Practice 20
GeeksforGeeks 10
unordered_map 输出
解释:此输出所证明的具体内容是,unordered_map 的结果值是以随机的键到值的方式生成的,而 map 以有序的方式显示值和键。
unordered_map 与 unordered_set
无序映射 | Unordered_set |
---|---|
Unordered_map 仅包含(键值)对形式的元素。 | Unordered_set 不一定包含键值对形式的元素,这些主要用于查看集合的存在/不存在。 |
运算符“ []”用于提取映射中存在的键的对应值。 | 使用find () 函数搜索元素。因此不需要运算符 []。 |
注意:例如,考虑计算单个单词频率的问题。我们不能使用 unordered_set(或 set),因为我们无法存储计数,但我们可以使用 unordered_map。
无序映射 | 地图 |
---|---|
unordered_map 键可以按任意顺序存储。 | 地图是唯一键的有序序列 |
Unordered_Map 实现了不平衡的树结构,因此无法维持元素之间的顺序 | Map 实现了平衡树结构,因此可以保持元素之间的顺序(通过特定的树遍历) |
unordered_map操作的时间复杂度平均为O(1)。 | map操作的时间复杂度为O(log n) |
unordered_map 上的方法
有很多函数可用于 unordered_map。其中最有用的是:
operator =
operator []
empty
size for capacity
begin and end for the iterator.
find and count for lookup.
insert and erase for modification.
下表显示了 unordered_map 方法的完整列表:
方法/函数 | 描述 |
---|---|
at() | C++ unordered_map 中的这个函数返回以元素为键 k 的值的引用 |
begin() | 返回指向 unordered_map 容器中第一个元素的迭代器 |
end() | 返回指向 unordered_map 容器中最后一个元素之后位置的迭代器 |
bucket() | 返回键为 k 的元素在映射中所在的桶编号 |
bucket_count | Bucket_count 用于计算 unordered_map 中 bucket 的总数。此函数无需传递任何参数 |
bucket_size | 返回 unordered_map 中每个 bucket 的元素数量 |
count() | 计算 unordered_map 中具有给定键的元素数量 |
equal_range | 返回包含容器中所有键等于 k 的元素的范围的边界 |
find() | 返回元素的迭代器 |
empty() | 检查unordered_map容器中容器是否为空 |
erase() | 擦除unordered_map容器中的元素 |
C++11 库还提供了查看内部使用的 bucket 计数、bucket 大小以及使用的哈希函数和各种哈希策略的函数,但它们在实际应用中用处不大。我们可以使用 Iterator 迭代 unordered_map 的所有元素。
// C++ program to demonstrate
// Initialization, indexing,
// and iteration
#include <iostream>
#include <unordered_map>
using namespace std;
// Driver code
int main()
{
// Declaring umap to be of
// <string, double> type key
// will be of string type and
// mapped value will be of double type
unordered_map<string, double> umap = { //inserting element directly in map
{"One", 1},
{"Two", 2},
{"Three", 3}
};
// inserting values by using [] operator
umap["PI"] = 3.14;
umap["root2"] = 1.414;
umap["root3"] = 1.732;
umap["log10"] = 2.302;
umap["loge"] = 1.0;
// inserting value by insert function
umap.insert(make_pair("e", 2.718));
string key = "PI";
// If key not found in map iterator
// to end is returned
if (umap.find(key) == umap.end())
cout << key << " not found\n\n";
// If key found then iterator to that
// key is returned
else
cout << "Found " << key << "\n\n";
key = "lambda";
if (umap.find(key) == umap.end())
cout << key << " not found\n";
else
cout << "Found " << key << endl;
// iterating over all value of umap
unordered_map<string, double>::iterator itr;
cout << "\nAll Elements : \n";
for (itr = umap.begin();
itr != umap.end(); itr++)
{
// itr works as a pointer to
// pair<string, double> type
// itr->first stores the key part and
// itr->second stores the value part
cout << itr->first << " " <<
itr->second << endl;
}
}
输出
找到 PI
lambda 未找到
所有元素:
e 2.718
loge 1
log10 2.302
Two 2
One 1
Three 3
PI 3.14
root2 1.414
root3 1.732
查找单个单词的频率
给定一串单词,任务是找出各个单词的频率:
输入: str = “geeks for geeks geeks quiz practice qa for”;
输出:单个单词的频率为
(practice, 1)
(for, 2)
(qa, 1)
(quiz, 1)
(geeks, 3)
下面是实现上述方法的 C++ 程序:
// C++ program to find freq
// of every word using unordered_map
#include <bits/stdc++.h>
using namespace std;
// Prints frequencies of
// individual words in str
void printFrequencies(const string &str)
{
// declaring map of <string, int> type,
// each word is mapped to its frequency
unordered_map<string, int> wordFreq;
// breaking input into word using
// string stream
// Used for breaking words
stringstream ss(str);
// To store individual words
string word;
while (ss >> word)
wordFreq[word]++;
// now iterating over word, freq pair
// and printing them in <, > format
unordered_map<string, int>:: iterator p;
for (p = wordFreq.begin();
p != wordFreq.end(); p++)
cout << "(" << p->first << ", " <<
p->second << ")\n";
}
// Driver code
int main()
{
string str = "geeks for geeks geeks quiz "
"practice qa for";
printFrequencies(str);
return 0;
}
输出
(practice, 1)
(for, 2)
(qa, 1)
(quiz, 1)
(geeks, 3)