STL标准库-一个万用的hash function
技术在于交流、沟通,本文为博主原创文章转载请注明出处并保持作品的完整性
在前面我介绍过hash的使用,本次主要介绍一下Hash Function
Hash Function即获得hash code的函数,根据其获得的hash code放到指定的bucket中,那么为了保证其hash的效率我们应尽量避免碰撞,所以hash Function所产生的hash code应足够的乱
下面介绍一个万用的hash function及其测试代码
首先我们创建一个客户类,它有三个成员变量 姓,名,年龄
class Customer
{
public:
string mFirstName;
string mLastName;
string mAge;
Customer(string firstName, string lastName, string age):mFirstName(firstName),mLastName(lastName),mAge(age){}
};
下面我们来创建hash function
class CustomerHash
{
public:
std::size_t operator()(const Customer& c) const
{
return hash_val(c.mFirstName, c.mLastName, c.mAge);
} template <typename... Types>
size_t hash_val(const Types&... args)const
{
size_t seed = ;//seed 为需要返回的hash code
hash_value(seed, args...);//C++11 新语法 我在http://www.cnblogs.com/LearningTheLoad/p/7208680.html中有介绍
return seed;
} template <typename T, typename... Types>
void hash_value(size_t& seed,
const T& firstArg,
const Types&... args) const
{
hash_combine(seed, firstArg);
hash_value(seed, args...);
} template <typename T>
void hash_value(size_t& seed,
const T& val) const //参数仅剩一个时
{
hash_combine(seed, val);
} template<typename T>
void hash_combine(size_t& seed,
const T& val) const
{
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << ) + (seed >> ); //0x9e3779b9 黄金分割比例
}
};
测试代码
int main(int argc, char *argv[])
{
unordered_multiset<Customer, CustomerHash> set; set.insert(Customer("a", "b", ""));
set.insert(Customer("c", "d", ""));
set.insert(Customer("e", "f", ""));
set.insert(Customer("g", "h", "")); int myBucket_count = set.bucket_count();//返回有多少个篮子
cout << set.bucket_count() << endl; CustomerHash hh;
cout << "bucket postion of " << hh(Customer("a", "b", "")) %myBucket_count << endl;//取余后 得出落在哪个篮子上
cout << "bucket postion of " << hh(Customer("c", "d", "")) %myBucket_count << endl;
cout << "bucket postion of " << hh(Customer("e", "f", "")) %myBucket_count << endl;
cout << "bucket postion of " << hh(Customer("a", "b", "")) %myBucket_count << endl; for (int i = ; i< myBucket_count; i++)
{//检测落在哪个篮子上
cout << "bucket at #: " << i << "has: " << set.bucket_size(i) << endl;
}
return ;
}
测试结果

全部测试代码
#include <iostream>
#include <unordered_set> using namespace std; class Customer
{
public:
string mFirstName;
string mLastName;
string mAge; Customer(string firstName, string lastName, string age):mFirstName(firstName),mLastName(lastName),mAge(age){} operator ==(const Customer& c) const
{
return (mFirstName == c.mFirstName && mLastName == c.mLastName && mAge == c.mAge);
}
}; class CustomerHash
{
public:
std::size_t operator()(const Customer& c) const
{
return hash_val(c.mFirstName, c.mLastName, c.mAge);
} template <typename... Types>
size_t hash_val(const Types&... args)const
{
size_t seed = ;
hash_value(seed, args...);
return seed;
} template <typename T, typename... Types>
void hash_value(size_t& seed,
const T& firstArg,
const Types&... args) const
{
hash_combine(seed, firstArg);
hash_value(seed, args...);
} template <typename T>
void hash_value(size_t& seed,
const T& val) const
{
hash_combine(seed, val);
} template<typename T>
void hash_combine(size_t& seed,
const T& val) const
{
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << ) + (seed >> );
}
}; int main(int argc, char *argv[])
{
unordered_multiset<Customer, CustomerHash> set; set.insert(Customer("a", "b", ""));
set.insert(Customer("c", "d", ""));
set.insert(Customer("e", "f", ""));
set.insert(Customer("g", "h", "")); int myBucket_count = set.bucket_count();
cout << set.bucket_count() << endl; CustomerHash hh;
cout << "bucket postion of " << hh(Customer("a", "b", "")) %myBucket_count << endl;
cout << "bucket postion of " << hh(Customer("c", "d", "")) %myBucket_count << endl;
cout << "bucket postion of " << hh(Customer("e", "f", "")) %myBucket_count << endl;
cout << "bucket postion of " << hh(Customer("a", "b", "")) %myBucket_count << endl; for (int i = ; i< myBucket_count; i++)
{
cout << "bucket at #: " << i << "has: " << set.bucket_size(i) << endl;
}
return ;
}
这是一个万用的hash function ,在我们自定义hash function时就可以定义为上面的函数
参考侯捷<<STL源码剖析>>
STL标准库-一个万用的hash function的更多相关文章
- STL标准库-容器-set与multiset
技术在于交流.沟通,转载请注明出处并保持作品的完整性. set与multiset关联容器 结构如下 set是一种关联容器,key即value,value即key.它是自动排序,排序特点依据key se ...
- STL标准库-容器-deque
技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. deque双向开口可进可出的容器 我们知道连续内存的容器不能随意扩充,因为这样容易扩充别人那去 deque却可以,它创造了内存 ...
- STL标准库-容器-vector
技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. 向量容器vector是一个动态数组,内存连续,它是动态分配内存,且每次扩张的原来的二倍. 他的结构如下 一 定义 vector ...
- C++STL标准库学习笔记(五)set
前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来,这一篇后面主要都是我的记录了,为了防止大片蓝色字体出现,后面就不改蓝色 ...
- C++STL标准库学习笔记(三)multiset
C++STL标准库学习笔记(三)multiset STL中的平衡二叉树数据结构 前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标 ...
- C++STL标准库学习笔记(二)二分查找
二.STL中的二分查找算法 1.binary_search 2.lower_bound 3.upper_bound 记得#include<algorithm>! 前言: 在这个笔记中,我把 ...
- STL标准库-算法-常用算法
技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 介绍11种STL标准库的算法,从这11种算法中总结一下算法的基本使用 1.accumulate() 累加 2.for_each( ...
- STL标准库-容器-set与map
STL标准库-容器-set与multiset C++的set https://www.cnblogs.com/LearningTheLoad/p/7456024.html STL标准库-容器-map和 ...
- C++STL标准库学习笔记(一)sort
前言: 近来在学习STL标准库,做一份笔记并整理好,方便自己梳理知识.以后查找,也方便他人学习,两全其美,快哉快哉! 这里我会以中国大学慕课上北京大学郭炜老师的<程序设计与算法(一)C语言程序设 ...
随机推荐
- IIS中添加ftp站点
1.创建Windows账号 右击点击“我的电脑”,选择“管理”打开服务器管理的控制台.展开“服务器管理器”,一路展开“配置”.“本地用户和组”,点“用户”项.然后在右边空白处点右键,选择“新用户”将打 ...
- darknet-训练自己的yolov3模型
目录 Yolo v3的使用方法 安装darknet 训练Pascal VOC格式的数据 修改cfg文件中的voc.data 修改VOC.names 下载预训练卷积层权重 修改cfg/yolov3-vo ...
- POJ 3628 Bookshelf2(0-1背包)
http://poj.org/problem?id=3628 题意:给出一个高度H和n个牛的高度,要求把牛堆叠起来达到H,求出该高度和H的最小差. 思路:首先我们计算出牛的总高度sum,sum-H就相 ...
- 词云wordcloud类介绍&python制作词云图&词云图乱码问题等小坑
词云图,大家一定见过,大数据时代大家经常见,我们今天就来用python的第三方库wordcloud,来制作一个大数据词云图,同时会降到这个过程中遇到的各种坑, 举个例子,下面是我从自己的微信上抓的微信 ...
- 字典重复key的合并
from collections import defaultdict d=defaultdict(set) s=[("001","A"),("001 ...
- 【转】xml节点解析成字符串的方法
网址:http://blog.csdn.net/shanzhizi/article/details/8817532 ZC: 这是 libxml2的 之前汇总了一篇关于xml文档与字符串转换的文章,文章 ...
- [设计模式][c++]状态切换模式
转自:http://blog.csdn.net/yongh701/article/details/49154439 状态模式也是设计模式的一种,这种设计模式思想不复杂,就是实现起来的代码有点复杂.主要 ...
- 《A_Pancers》第二次作业 基于Android系统的音乐播放系统项目开题报告
小组名 N A B C D 总分 Just_Do_IT! 8 8 9 9 8 42 Miracle-House 8 8 7 8 8 39 ymm3 9 8 8 8 8 41 Spring_Four ...
- 《剑指offer》第二十六题(树的子结构)
// 面试题26:树的子结构 // 题目:输入两棵二叉树A和B,判断B是不是A的子结构. #include <iostream> struct BinaryTreeNode { doubl ...
- Flutter学习笔记(一)
记得flutter出来的时候,官方推荐的是使用IntelliJ IDEA,当时个人尝试了一下,比较麻烦,整个过程比较漫长. 进入2018年,再去看的时候,官方推荐使用Android Studio和VS ...