转载自 这里
目录
std::erase_if (std::unordered_map)
简介
本篇博客介绍C++常用的无序关联容器unordered_map。unordered_map是C++11正式加入的对hash_map的官方实现(之前标准C++没有hash_map的官方实现,我们使用的STL的hash_map并不是官方的)。从名字可以看出这个结构是无序的,底层设计思想和STL的hash_map一样。元素在内部不以任何特定顺序排序,而是放进桶中。元素放进哪个桶完全依赖于其键的哈希。这允许对单独元素的快速访问,因为一旦计算哈希,则它准确指代元素所放进的桶。unordered_map搜索、插入和元素移除拥有平均常数时间复杂度。
查找元素

at()用于访问指定元素
-
T& at( const Key& key ); -
const T& at( const Key& key ) const;
返回到等于 key 的键的元素的引用。若无该元素,则抛出 std::out_of_range 类型异常。
operator []用于访问或插入元素
-
T& operator[]( const Key& key ); -
T& operator[]( Key&& key );
返回等于 key 的键的值的引用。如果该键不存在,则执行插入,反之,则覆盖原来的值。
-
#include <iostream> -
#include <string> -
#include <vector> -
#include <unordered_map> -
int main() -
{ -
std::unordered_map<char, int> letter_counts {{'a', 27}, {'b', 3}, {'c', 1}}; -
std::cout << "initially:\n"; -
for (const auto &pair : letter_counts) { -
std::cout << pair.first << ": " << pair.second << '\n'; -
} -
letter_counts['b'] = 42; // 更新既存值 -
letter_counts['x'] = 9; // 插入新值 -
std::cout << "after modifications:\n"; -
for (const auto &pair : letter_counts) { -
std::cout << pair.first << ": " << pair.second << '\n'; -
} -
// 统计每个词的出现数 -
// (首次调用 operator[] 以零初始化计数器) -
std::unordered_map<std::string, size_t> word_map; -
for (const auto &w : { "this", "sentence", "is", "not", "a", "sentence", -
"this", "sentence", "is", "a", "hoax"}) { -
++word_map[w]; -
} -
for (const auto &pair : word_map) { -
std::cout << pair.second << " occurrences of word '" << pair.first << "'\n"; -
} -
} -
输出: -
initially: -
a: 27 -
b: 3 -
c: 1 -
after modifications: -
a: 27 -
b: 42 -
c: 1 -
x: 9 -
2 occurrences of word 'a' -
1 occurrences of word 'hoax' -
2 occurrences of word 'is' -
1 occurrences of word 'not' -
3 occurrences of word 'sentence' -
2 occurrences of word 'this'
count() 返回特定键的元素数量
-
(1)size_type count( const Key& key ) const; -
(2)template< class K > -
size_type count( const K& x ) const;
(1) 返回等于指定参数 key 的键的元素数,因为此容器不允许重复,故返回值为 0 或 1 。
(2) 返回键等于指定参数 x 的元素数。此重载仅若有限定标识 Hash::is_transparent 与 KeyEqual::is_transparent 均合法并指代类型才参与重载决议。这假设能用 K 和 Key 类型一起调用这种 Hash ,还有 KeyEqual 是通透的,进而允许不用构造 Key 的实例就调用此函数。
find()寻找特定键的元素
-
(1)iterator find( const Key& key ); -
(2)const_iterator find( const Key& key ) const; -
(3)template< class K > iterator find( const K& x ); -
(4)template< class K > const_iterator find( const K& x ) const;
(1-2) 寻找键等于 key 的的元素。
(3-4) 寻找键等于值 x 的元素。此重载仅若有限定标识 Hash::is_transparent 与 KeyEqual::is_transparent 均合法并指代类型才参与重载决议。这假设能用 K 和 Key 类型一起调用这种 Hash ,还有 KeyEqual 是通透的,进而允许不用构造 Key 的实例就调用此函数。
-
#include <iostream> -
#include <unordered_map> -
int main() -
{ -
// 简单比较演示 -
std::unordered_map<int,char> example = {{1,'a'},{2,'b'}}; -
auto search = example.find(2); -
if (search != example.end()) { -
std::cout << "Found " << search->first << " " << search->second << '\n'; -
} else { -
std::cout << "Not found\n"; -
} -
} -
输出: -
Found 2 b
contains()可检查容器是否含有特定键的元素
-
(1)bool contains( const Key& key ) const; -
(2)template< class K > bool contains( const K& x ) const;
(1) 检查容器中是否有键等于 key 的元素。
(2) 检查是否有键等于值 x 的元素。此重载仅若有限定标识 Hash::is_transparent 与 KeyEqual::is_transparent 均合法并指代类型才参与重载决议。这假设能用 K 和 Key 类型一起调用这种 Hash ,还有 KeyEqual 是通透的,进而允许不用构造 Key 的实例就调用此函数。
-
#include <iostream> -
#include <unordered_map> -
int main() -
{ -
std::unordered_map<int,char> example = {{1,'a'},{2,'b'}}; -
if (example.contains(2)) { -
std::cout << "Found\n"; -
} else { -
std::cout << "Not found\n"; -
} -
} -
输出: -
Found
find()的返回值是迭代器,若有元素,可以直接通过返回的迭代器获取元素信息。 而contains()的返回值是bool型,只用于确定是否包含该元素。
equal_range()返回匹配特定键的元素范围
-
(1)std::pair<iterator,iterator> equal_range( const Key& key ); -
(2)std::pair<const_iterator,const_iterator> equal_range( const Key& key ) const; -
(3)template< class K > -
std::pair<iterator,iterator> equal_range( const K& x ); -
(4)template< class K > -
std::pair<const_iterator,const_iterator> equal_range( const K& x ) const;
(1-2) 返回容器中所有键等于 key 的元素范围。范围以两个迭代器定义,第一个指向所需范围的首元素,而第二个指向范围的尾后一位元素。
(3-4) 返回含有容器中所有键等于 x 的元素的范围。此重载仅若有限定标识 Hash::is_transparent 与 KeyEqual::is_transparent 均合法并指代类型才参与重载决议。这假设能用 K 和 Key 类型一起调用这种 Hash ,还有 KeyEqual 是通透的,进而允许不用构造 Key 的实例就调用此函数。
-
#include <iostream> -
#include <unordered_map> -
int main() -
{ -
std::unordered_map<int,char> map = {{1,'a'},{1,'b'},{1,'d'},{2,'b'}}; -
auto range = map.equal_range(1); -
for (auto it = range.first; it != range.second; ++it) { -
std::cout << it->first << ' ' << it->second << '\n'; -
} -
} -
输出: -
1 a
迭代器

begin() & cbegine()
-
iterator begin() noexcept; -
const_iterator begin() const noexcept; -
const_iterator cbegin() const noexcept;
返回指向 unordered_map 首元素的迭代器。若 unordered_map 为空,则返回的迭代器将等于 end()。
end() & cend()
-
iterator end() noexcept; -
const_iterator end() const noexcept; -
const_iterator cend() const noexcept;
返回指向 unordered_map 最后一个元素的之后的迭代器。此元素表现为占位符;试图访问它导致未定义行为。
-
#include <cmath> -
#include <iostream> -
#include <unordered_map> -
struct Node { double x, y; }; -
int main() { -
Node nodes[3] = { {1, 0}, {2, 0}, {3, 0} }; -
// mag 是将 Node 的地址映射到其在平面中的模的映射 -
std::unordered_map<Node *, double> mag = { -
{ nodes, 1 }, -
{ nodes + 1, 2 }, -
{ nodes + 2, 3 } -
}; -
// 将每个 y 坐标从 0 更改到模 -
for(auto iter = mag.begin(); iter != mag.end(); ++iter){ -
auto cur = iter->first; // 指向 Node 的指针 -
cur->y = mag[cur]; // 可以也使用 cur->y = iter->second; -
} -
// 更新并打印每个结点的模 -
for(auto iter = mag.begin(); iter != mag.end(); ++iter){ -
auto cur = iter->first; -
mag[cur] = std::hypot(cur->x, cur->y); -
std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is "; -
std::cout << iter->second << '\n'; -
} -
// 以基于范围的 for 循环重复上述者 -
for(auto i : mag) { -
auto cur = i.first; -
cur->y = i.second; -
mag[cur] = std::hypot(cur->x, cur->y); -
std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is "; -
std::cout << mag[cur] << '\n'; -
// 注意与 std::cout << iter->second << '\n'; 相反,上述的 -
// std::cout << i.second << '\n'; 不会打印更新的模 -
} -
} -
输出: -
The magnitude of (1, 1) is 1.41421 -
The magnitude of (2, 2) is 2.82843 -
The magnitude of (3, 3) is 4.24264 -
The magnitude of (1, 1.41421) is 1.73205 -
The magnitude of (2, 2.82843) is 3.4641 -
The magnitude of (3, 4.24264) is 5.19615
容量

empty() 用于检查容器是否为空
-
bool empty() const noexcept; -
[[nodiscard]] bool empty() const noexcept;
size() 返回容纳的元素数量
size_type size() const noexcept;
返回容器中的元素数,即std::distance(begin(), end()) 。
-
int main() -
{ -
std::unordered_map<int,char> nums {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}}; -
std::cout << "nums contains " << nums.size() << " elements.\n"; -
} -
输出: -
nums contains 4 elements.
max_size() 返回最大可容纳的元素数
size_type max_size() const noexcept;
返回根据系统或库实现限制的容器可包含的元素最大数量,即对于最大容器的 std::distance(begin(), end()) 。
-
#include <iostream> -
#include <unordered_map> -
int main() -
{ -
std::unordered_map<char,char> s; -
std::cout << "Maximum size of a 'unordered_map' is " << s.max_size() << "\n"; -
} -
输出: -
Maximum size of a 'unordered_map' is 768614336404564650
修改操作

clear()
void clear() noexcept;
从容器去除所有元素。此调用后 size() 返回零。非法化任何指代所含元素的引用、指针或迭代器。可能亦非法化尾后迭代器。
insert()
-
(1)std::pair<iterator,bool> insert( const value_type& value ); -
std::pair<iterator,bool> insert( value_type&& value ); -
(2)template< class P > -
std::pair<iterator,bool> insert( P&& value ); -
(3)iterator insert( const_iterator hint, const value_type& value ); -
iterator insert( const_iterator hint, value_type&& value ); -
(4)template< class P > -
iterator insert( const_iterator hint, P&& value ); -
(5)template< class InputIt > -
void insert( InputIt first, InputIt last ); -
(6)void insert( std::initializer_list<value_type> ilist ); -
(7)insert_return_type insert(node_type&& nh); -
(8)iterator insert(const_iterator hint, node_type&& nh);
若容器尚未含有带等价关键的元素,则插入元素到容器中。
(1-2) 插入 value 。重载 (2) 等价于 emplace(std::forward<P>(value)) ,且仅若 std::is_constructible<value_type, P&&>::value == true 才参与重载决议。
(3-4) 插入 value ,以 hint 为应当开始搜索的位置的非强制建议。重载 (4) 等价于 emplace_hint(hint, std::forward<P>(value)) ,且仅若 std::is_constructible<value_type, P&&>::value == true 才参与重载决议。
(5) 插入来自范围 [first, last) 的元素。若范围中的多个元素拥有比较等价的关键,则插入哪个元素是未指定的。
(6) 插入来自 initializer_list ilist 的元素。若范围中的多个元素拥有比较等价的关键,则插入哪个元素是未指定的。
(7) 若 nh 是空的结点句柄,则不做任何事。否则插入 nh 所占有的元素到容器,若容器尚未含有拥有等价于 nh.key() 的关键的元素。若 nh 非空且 get_allocator() != nh.get_allocator() 则行为未定义。
(8) 若 nh 是空的结点句柄,则不做任何事并返回尾迭代器。否则,插入 nh 所占有的元素到容器,若容器尚未含有拥有等价于 nh.key() 的关键的元素,并返回指向拥有等于 nh.key() 的关键的元素的迭代器(无关乎插入成功还是失败)。若插入成功,则从 nh 移动,否则它保持该元素的所有权。元素被插入到尽可能接近 hint 的位置。若 nh 非空且 get_allocator() != nh.get_allocator() 则行为未定义。
若因插入发生重哈希,则所有迭代器都被非法化。否则迭代器不受影响。引用不受影响。重哈希仅若新元素数量大于 max_load_factor()*bucket_count() 才发生。若插入成功,则在结点把柄保有元素时获得的指向该元素的指针和引用被非法化,而在提取前获得的指向元素的指针和引用变得合法。
-
#include <string> -
#include <iostream> -
#include <unordered_map> -
int main () -
{ -
std::unordered_map<int, std::string> dict = {{1, "one"}, {2, "two"}}; -
dict.insert({3, "three"}); -
dict.insert(std::make_pair(4, "four")); -
dict.insert({{4, "another four"}, {5, "five"}}); -
bool ok = dict.insert({1, "another one"}).second; -
std::cout << "inserting 1 -> \"another one\" " -
<< (ok ? "succeeded" : "failed") << '\n'; -
std::cout << "contents:\n"; -
for(auto& p: dict) -
std::cout << " " << p.first << " => " << p.second << '\n'; -
} -
输出: -
inserting 1 -> "another one" failed -
contents: -
5 => five -
1 => one -
2 => two -
3 => three -
4 => four
insert_or_assign()
-
(1)template <class M> -
pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); -
(2)template <class M> -
pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); -
(3)template <class M> -
iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); -
(4)template <class M> -
iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
(1,3) 若等价于 k 的键已存在于容器中,则赋值 std::forward<M>(obj) 给对应于键 k 的 mapped_type 。若键不存在,则如同用 insert 插入从 value_type(k, std::forward<M>(obj)) 构造的新值。
(2,4) 同 (1,3) ,除了从 value_type(std::move(k), std::forward<M>(obj)) 构造被映射值。
若插入发生且导致容器的重哈希,则所有迭代器被非法化。否则迭代器不受影响。重哈希仅若新元素数量大于 max_load_factor()*bucket_count() 才发生。
-
#include <iostream> -
#include <unordered_map> -
#include <string> -
int main() -
{ -
std::unordered_map<std::string, std::string> myMap; -
myMap.insert_or_assign("a", "apple" ); -
myMap.insert_or_assign("b", "bannana" ); -
myMap.insert_or_assign("c", "cherry" ); -
myMap.insert_or_assign("c", "clementine"); -
for (const auto &pair : myMap) { -
std::cout << pair.first << " : " << pair.second << '\n'; -
} -
} -
输出: -
c : clementine -
a : apple -
b : bannana
emplace()
-
template< class... Args > -
std::pair<iterator,bool> emplace( Args&&... args );
若容器中无拥有该关键的元素,则插入以给定的 args 原位构造的新元素到容器。
细心地使用 emplace 允许在构造新元素的同时避免不必要的复制或移动操作。 准确地以与提供给 emplace 者相同的参数,通过std::forward<Args>(args)... 转发调用新元素(即 std::pair<const Key, T> )的构造函数。 即使容器中已有拥有该关键的元素,也可能构造元素,该情况下新构造的元素将被立即销毁。
若因插入发生重哈希,则所有迭代器都被非法化。否则迭代器不受影响。引用不被非法化。重哈希仅若新元素数量大于 max_load_factor()*bucket_count() 才发生。
-
#include <iostream> -
#include <utility> -
#include <string> -
#include <unordered_map> -
int main() -
{ -
std::unordered_map<std::string, std::string> m; -
// 使用 pair 的移动构造函数 -
m.emplace(std::make_pair(std::string("a"), std::string("a"))); -
// 使用 pair 的转换移动构造函数 -
m.emplace(std::make_pair("b", "abcd")); -
// 使用 pair 的模板构造函数 -
m.emplace("d", "ddd"); -
// 使用 pair 的逐片构造函数 -
m.emplace(std::piecewise_construct, -
std::forward_as_tuple("c"), -
std::forward_as_tuple(10, 'c')); -
// C++17 起,能使用 m.try_emplace("c", 10, 'c'); -
for (const auto &p : m) { -
std::cout << p.first << " => " << p.second << '\n'; -
} -
} -
输出: -
a => a -
b => abcd -
c => cccccccccc -
d => ddd
-
#include <unordered_map> -
#include <iostream> -
#include <utility> -
int main() -
{ -
std::unordered_map<int, int> numbers; -
std::cout << "Initially, numbers.empty(): " << numbers.empty() << '\n'; -
numbers.emplace(42, 13); -
numbers.insert(std::make_pair(13317, 123)); -
std::cout << "After adding elements, numbers.empty(): " << numbers.empty() << '\n'; -
} -
输出: -
Initially, numbers.empty(): 1 -
After adding elements, numbers.empty(): 0
emplace_hint()
-
template <class... Args> -
iterator emplace_hint( const_iterator hint, Args&&... args );
插入新元素到容器,以 hint 为应当放置新元素位置的建议。原位构造元素,即不进行复制或移动操作。
准确地以与提供给函数者相同的参数,以 std::forward<Args>(args)... 转发调用元素类型( value_type 即 std::pair<const Key, T> )的构造函数。
若因插入发生重哈希,则所有迭代器都被非法化。否则迭代器不受影响。引用不被非法化。重哈希仅若新元素数量大于 max_load_factor()*bucket_count() 才发生。
try_emplace()
-
(1)template <class... Args> -
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); -
(2)template <class... Args> -
pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); -
(3)template <class... Args> -
iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); -
(4)template <class... Args> -
iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
(1) 若容器中已存在等价于 k 的关键,则不做任何事。否则行为类似 emplace ,除了以 value_type(std::piecewise_construct, std::forward_as_tuple(k), std::forward_as_tuple(std::forward<Args>(args)...)) 构造元素。
(2) 若容器中已存在等价于 k 的关键,则不做任何事。否则行为类似 emplace ,除了以 value_type(std::piecewise_construct, std::forward_as_tuple(std::move(k)), std::forward_as_tuple(std::forward<Args>(args)...)) 构造元素。
(3) 若容器中已存在等价于 k 的关键,则不做任何事。否则行为类似 emplace_hint ,除了以 value_type(std::piecewise_construct, std::forward_as_tuple(k), std::forward_as_tuple(std::forward<Args>(args)...)) 构造元素。
(4) 若容器中已存在等价于 k 的关键,则不做任何事。否则行为类似 emplace_hint ,除了以 value_type(std::piecewise_construct, std::forward_as_tuple(std::move(k)), std::forward_as_tuple(std::forward<Args>(args)...)) 构造元素。
若因插入发生重哈希,则所有迭代器都被非法化。否则迭代器不受影响。引用不被非法化。重哈希仅若新元素数量大于 max_load_factor()*bucket_count() 才发生。
-
#include <iostream> -
#include <utility> -
#include <string> -
#include <unordered_map> -
int main() -
{ -
using namespace std::literals; -
std::unordered_map<std::string, std::string> m; -
m.try_emplace("a", "a"s); -
m.try_emplace("b", "abcd"); -
m.try_emplace("c", 10, 'c'); -
m.try_emplace("c", "Won't be inserted"); -
for (const auto &p : m) { -
std::cout << p.first << " => " << p.second << '\n'; -
} -
} -
输出: -
a => a -
b => abcd -
c => cccccccccc
erase()
-
(1)iterator erase( const_iterator pos ); -
(2)iterator erase( const_iterator first, const_iterator last ); -
(3)size_type erase( const key_type& key );
从容器移除指定的元素。
(1) 移除位于 pos 的元素。
(2) 移除范围 [first; last) 中的元素,它必须是 *this 中的合法范围。
(3) 移除键等于 key 的元素(若存在一个)。
到被去除元素的引用和迭代器被非法化,其他迭代器和引用不被非法化。迭代器 pos 必须合法且可解引用,从而使得 end() 迭代器(合法,但不可解引用)不能用作 pos 所用的值。保留未被擦除的元素顺序(这使得可能在迭代通过容器时擦除单独的元素)。
-
#include <unordered_map> -
#include <iostream> -
int main() -
{ -
std::unordered_map<int, std::string> c = {{1, "one"}, {2, "two"}, {3, "three"}, -
{4, "four"}, {5, "five"}, {6, "six"}}; -
// 从 c 擦除所有奇数 -
for(auto it = c.begin(); it != c.end(); ) -
if(it->first % 2 == 1) -
it = c.erase(it); -
else -
++it; -
for(auto& p : c) -
std::cout << p.second << ' '; -
} -
输出: -
two four six
swap()
-
void swap( unordered_map& other ); -
void swap( unordered_map& other ) noexcept();
将内容与 other 的交换,不在单个元素上调用任何移动、复制或交换操作。所有迭代器和引用保持合法,尾后迭代器被非法化。
Hash 和 KeyEqual 对象必须可交换 (Swappable) ,并用非成员 swap 的非限定调用交换它们。
extract()
-
(1)node_type extract( const_iterator position ); -
(2)node_type extract( const key_type& x );
(1) 解链含 position 所指向元素的结点并返回占有它的结点句柄。
(2) 若容器拥有元素而其关键等于 x ,则从容器解链该元素并返回占有它的结点句柄。否则,返回空结点把柄。任何情况下,均不复制或移动元素,只重指向容器结点的内部指针。
释出结点只会非法化指向被释出元素的迭代器,并保持未被去除元素的相对顺序。指向被释出元素的指针和引用保持合法,但在结点句柄占有该元素时不能使用:若元素被插入容器,就能使用它们。
注意:extract 是更换键而不重分配的唯一方式。
-
unordered_map<int, string> m{{1, "mango"}, {2, "papaya"}, {3, "guava"}}; -
auto nh = m.extract(2); -
nh.key() = 4; -
m.insert(move(nh));
merge()
-
(1)template<class H2, class P2> -
void merge(std::unordered_map<Key, T, H2, P2, Allocator>& source); -
(2)template<class H2, class P2> -
void merge(std::unordered_map<Key, T, H2, P2, Allocator>&& source); -
(3)template<class H2, class P2> -
void merge(std::unordered_multimap<Key, T, H2, P2, Allocator>& source); -
(4)template<class H2, class P2> -
void merge(std::unordered_multimap<Key, T, H2, P2, Allocator>&& source);
试图释出("接合") source 中每个元素,并用 *this 的哈希函数和关键相等谓词插入到 *this 。 若 *this 中有元素,其关键等价于来自 source 中元素的关键,则不从 source 释出该元素。 不复制或移动元素,只会重指向容器结点的内部指针。指向被转移元素的所有指针和引用保持合法,但现在指代到 *this 中而非到 source 中。指代被转移元素的迭代器和所有指代到 *this 的迭代器被非法化。指向留在 source 中元素的迭代器保持合法。若 get_allocator() != source.get_allocator() 则行为未定义。
通接口

begin() & cbegin()
-
local_iterator begin( size_type n ); -
const_local_iterator begin( size_type n ) const; -
const_local_iterator cbegin( size_type n ) const;
返回指向下标为 n 的桶首元素的迭代器。
end() & cend()
-
local_iterator end( size_type n ); -
const_local_iterator end( size_type n ) const; -
const_local_iterator cend( size_type n ) const;
返回后随下标为 n 的桶的最后元素的元素的迭代器。此元素表现为占位符,试图访问它会导致未定义行为。
bucket_count() 返回容器中的桶数
size_type bucket_count() const;
max_bucket_count() 返回容器由于系统或库实现限制的能保有的最大桶数
size_type max_bucket_count() const;
bucket_size() 返回下标为 n 的桶中的元素数
size_type bucket_size( size_type n ) const;
bucket() 返回关键 key 的桶的下标
size_type bucket( const Key& key ) const;
始终会在此桶中找到关键等于 key 的元素(若存在)。返回值仅对 bucket_count() 返回相同值的容器实例合法。若 bucket_count() 为零则行为未定义。
哈希策略

load_factor()
float load_factor() const;
返回每个桶元素的平均数,即 size() 除以 bucket_count() 。
max_load_factor()
-
(1)float max_load_factor() const; -
(2)void max_load_factor( float ml );
管理最大加载因子(每个桶的平均元素数)。若加载因子超出此阈值,则容器自动增加桶数。
(1) 返回最大加载因子。
(2) 设置最大加载因子为 ml 。
rehash()
void rehash( size_type count );
设置桶数为 count 并重哈希容器,即考虑桶总数已改变,再把元素放到适当的桶中。若新的桶数使加载因子大于最大加载因子( count < size() / max_load_factor() ),则新桶数至少为 size() / max_load_factor() 。
reserve()
void reserve( size_type count );
设置桶数为适应至少 count 个元素,而不超出最大加载因子所需的数,并重哈希容器,即考虑桶数已更改后将元素放进适合的桶。等效地调用 rehash(std::ceil(count / max_load_factor())) 。
观察器

hash_function() 返回对关键哈希的函数
hasher hash_function() const;
key_eq() 返回比较关键相等性的函数
key_equal key_eq() const;
std::swap(std::unordered_map)
-
(1)template< class Key, class T, class Hash, class KeyEqual, class Alloc > -
void swap( unordered_map<Key,T,Hash,KeyEqual,Alloc>& lhs, -
unordered_map<Key,T,Hash,KeyEqual,Alloc>& rhs ); -
(2)template< class Key, class T, class Hash, class KeyEqual, class Alloc > -
void swap( unordered_map<Key,T,Hash,KeyEqual,Alloc>& lhs, -
unordered_map<Key,T,Hash,KeyEqual,Alloc>& rhs ) noexcept(/* see below */);
为 std::unordered_map 特化 std::swap 算法。交换 lhs 与 rhs 的内容。调用 lhs.swap(rhs) 。
std::erase_if (std::unordered_map)
-
template< class Key, class T, class Hash, class KeyEqual, class Alloc, class Pred > -
typename std::unordered_map<Key,T,Hash,KeyEqual,Alloc>::size_type -
erase_if(std::unordered_map<Key,T,Hash,KeyEqual,Alloc>& c, Pred pred); (C++20 起)
从容器中去除所有满足谓词 pred 的元素。等价于:
-
auto old_size = c.size();for (auto i = c.begin(), last = c.end(); i != last; ) { -
if (pred(*i)) { -
i = c.erase(i); -
} else { -
++i; -
}} -
return old_size - c.size();
这篇博客详细介绍了C++11中的unordered_map容器,包括其无序性、查找元素的方法(如at()、operator[]、count()、find()、contains())、迭代器操作、容量管理(如empty()、size()、max_size())、修改操作(如clear()、insert()、emplace()等)、哈希策略以及观察器函数。unordered_map提供了高效的元素查找和插入操作,适用于需要快速访问的数据结构。
6986

被折叠的 条评论
为什么被折叠?



