lambda 的组成部分 operator==类体和全局中的细微区别 哈希容器代码 自定义哈希函数

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…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值