文章目录
- C++学习笔记
- 知识点
- lambda 的组成部分:
- operator 重载运算符
- 哈希容器
- hash<K>
- 总结
C++学习笔记
知识点
lambda 的组成部分:
在 C++ 11 和更高版本中,Lambda 表达式(通常称为 Lambda)
是一种在被调用的位置或作为参数传递给函数的位置
定义匿名函数对象(闭包)的简便方法。
Lambda 通常用于封装传递给算法或异步函数的少量代码行。
operator 重载运算符
返回值类型 operator 运算符名称 (形参表列){
//TODO:
}
类体中被声明
重载的操作符在类体中被声明,声明方式如同普通成员函数一样,
只不过他的名字包含关键字operator,
以及紧跟其后的一个c++预定义的操作符。
可以用如下的方式来声明一个预定义的==操作符:
class person{
private:
int age;
public:
person(int a){
this->age=a;
}
inline bool operator == (const person &ps) const;
// 注意这里的const(==左值简写形式)
};
// 实现方式
inline bool person::operator==(const person &ps) const
{
if (this->age==ps.age)
return true;
return false;
}
全局声明
对于全局重载操作符,代表左操作数的参数
必须被显式指定
bool operator==(person const &p1 ,person const & p2)
//满足要求,做操作数的类型被显示指定
{
if(p1.age==p2.age)
return true;
return false;
}
哈希容器
unordered_map、
unordered_multimap、
unordered_set 以及
unordered_multiset
它们常被称为“无序容器”、“哈希容器”或者“无序关联容器”
hash
hash<K> 模板定义了可以从 K 类型的对象生成哈希值的函数对象的类型。
hash<K> 实例的成员函数 operator()() 接受 K 类型的单个参数,
然后返回 size_t 类型的哈希值。
对于基本类型和指针类型,也定义了特例化的 hash<K> 模板。
下面是一个用 hash
生成整数的哈希值的示例:
std::hash<int> hash_int;// Function object to hash int
std::vector<int> {-5, -2, 2, 5, 10};
std::transform(std::begin(n), std::end(n), std::ostream_iterator<size_t> (std:: cout," "), hash_int);
这里使用 transform() 算法来哈希 vector 中的元素。
transform() 参数中的前两个迭代器指定了被操作元素的范围,
第三个参数是一个指定输出地址的迭代器,这里是一个 ostream 迭代器,
最后一个参数是应用到范围元素上的函数对象 hash<int>
自定义哈希函数
struct HashFunc {
size_t operator () (const Type &o) const {
return ((hash<int>()(o.x) ^ (hash<string>()(o.y) << 1)) >> 1);
// 分别算出哈希值(int和string),然后对它们进行组合得到一个新的hash值
// 一般直接采用移位加异或(XOR) 便可得到基本够用的哈希值(碰撞不太频繁)
}
};
完整代码
#include <unordered_map>
#include <string>
#include <iostream>
using namespace std;
// 容器处理碰撞时,需要判断二者是否相等,必须提供判断相等的方法
// 建议重载“==”操作符
struct Type {
int x; string y;
bool operator == (const Type &a) const { // ==左值为const
return x == a.x && y == a.y;
}
};
struct HashFunc {
size_t operator () (const Type &o) const {
return ((hash<int>()(o.x) ^ (hash<string>()(o.y) << 1)) >> 1);
// 分别算出哈希值(int和string),然后对它们进行组合得到一个新的hash值
// 一般直接采用移位加异或(XOR) 便可得到基本够用的哈希值(碰撞不太频繁)
}
};
int main() {
unordered_map<Type, string, HashFunc> testHash = {
{ {1, "1"}, "one" },
{ {2, "2"}, "two" },
{ {3, "3"}, "three" },
{ {11, "1"}, "one" },
{ {12, "2"}, "two" },
{ {13, "3"}, "three" },
{ {21, "1"}, "one" },
{ {22, "2"}, "two" },
{ {23, "3"}, "three" }
};
for(auto mem : testHash) {
cout << mem.first.x << "," << mem.first.y << " - " << mem.second << endl;
}
}
输出结果
23,3 - three
21,1 - one
13,3 - three
22,2 - two
12,2 - two
11,1 - one
3,3 - three
2,2 - two
1,1 - one
总结
好好学习,天天向上,
Collect dots today
and connect them in the future…