转载自 这里
目录
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_ite