哈希表的定义和查找方法就不再赘述,此随笔主要写代码中的用法加深自己印象。
声明哈希表:
#include<unordered_map>
unordered_map<eleType_1, eleType_2> var_name;
unordered_map<int, int> map;
//或者之前用过的char int类型,char为key,int为char的值。后面的变量为两个
unordered_map<char, int> ans, arr;
初始化哈希表
//这是int型的
unordered_map<int,int> hmap{ {1,10},{2,15},{3,20},{4,0},{5,12}};
//这是以char为关键字
unordered_map<char, int> ans{ {a,1},{b,1},{c,1},{f,2}};
通过直接赋值来进行元素添加(类似数组)
//这里是把hamp的key对应的数值进行改变,例如
//把上面的{4,0}中的值改成了14,{5,12}中的值改成15
hmap[4] = 14;
hmap[5] = 15;
同时还有内置函数insert来实现元素插入
hamp.insert({5,15});
复制另一个不为空的哈希表,把hmap复制给tests
unordered_map<int,int>hmap{ {1,10},{2,8},{3,7}};
unordered_map<int,int> tests(hmap);
STL中的常用函数
//申请迭代器,把迭代器的位置赋值到哈希表起始位置
unordered_map<int,int>::iterator iter = hmap.begin();
cout << iter->first << ":" <<iter->second;
//下面等同于上面
unordered_map<char,int> ans;
unordered_map<char,int>::iterator iter = ans.begin()
unordered_map<char,int>::iterator tailer = ans.end()
1)begin函数,类似于return head,返回开始位置的迭代器,iterator是迭代器的类型
2)end函数,就是在哈希表的结尾位置的下一个元素的迭代器
如下copy-paste 解释
在 C++ 标准库的 unordered_map 中,.end() 返回的是一个指向容器末尾位置之后一个位置的迭代器。也就是说,tailer 指向的位置并不是容器中最后一个元素,而是超出容器实际元素范围的一个位置。这个位置通常被称为“哨兵”或“尾后迭代器”。
这意味着 tailer 不能用于访问任何有效的元素,如果试图解引用它(例如 *tailer),会导致未定义行为。因此,通常在迭代遍历容器时,用 iter != ans.end() 作为循环结束的条件,而不会试图访问 end() 所指向的位置。
int main() {
std::unordered_map<char, int> ans;
ans['a'] = 1;
ans['b'] = 2;
ans['c'] = 3;
// 申请迭代器并初始化为哈希表的末尾位置
std::unordered_map<char, int>::iterator tailer = ans.end();
// 遍历哈希表
for (std::unordered_map<char, int>::iterator iter = ans.begin(); iter != ans.end(); ++iter) {
std::cout << iter->first << ": " << iter->second << std::endl;
}
return 0;
3)cbegin和cend 这两个函数与begin|end的用法相同,只不过是"const"->即无法改变的“常”哈希表
const unordered_map<int,int> hmap{{1,10},{2,12},{3,12}};
unordered_map<int,int>::const_iterator iter_b = hmap.cbegin();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~iter_a = hmap.cend();
4)删除元素,hamp.erease()和clear()。
myMap.erase(1) //删除键为1的元素
myMap.clear() //清空整个哈希表
-----------------------------------------------------
std::unordered_map<int, std::string> myMap;
myMap[1] = "one";
myMap[2] = "two";
myMap[3] = "three";
myMap.erase(1);
/*哈希表中剩余元素有
2: two
3: three
*/
如果要删除所有值为特定值的元素,需要遍历整个哈希表
std::unordered_map<int, int> myMap;
myMap[1] = 10;
myMap[2] = 20;
myMap[3] = 10;
myMap[4] = 30;
// 遍历哈希表删除值为10的元素
for (auto it = myMap.begin(); it != myMap.end(); ) {
if (it->second == 10) {
it = myMap.erase(it); // erase 返回下一个元素的迭代器
} else {
++it;
}
}
// 遍历哈希表查看剩余元素
for (const auto &pair : myMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
这段代码中输出就是2:20 4:30,所有值为10的元素都被删除了。
上面大多用map来举例,C++中常用的还有unordered_set,unordered_set和unordered_map有一定区别,但都是基于哈希表实现的容器。其中:
- 数据存储类型:
- unordered_set:存储唯一的元素,没有重复值。它是一个集合,每个元素只能出现一次。
- unordered_map:存储键值对(key-value pairs),其中键是唯一的,但值可以重复。它是一个映射容器,每个键只能出现一次。之前我们举例都是基于此类型{1,10},{2,20}...
- 访问方式:
- unordered_set:只能通过元素值来访问,不支持通过索引访问。
- unordered_map:可以通过键来访问对应的值,类似于字典映射等。
- 插入操作:
- unordered_set:只能插入值,插入操作返回一个pair,第一个元素是一个迭代器,指向插入位置,第二个元素十一个bool 代表插入是否成功。
- unordered_map:插入是键值对,插入操作也返回一个pair,同set