技术在于交流、沟通,本文为博主原创文章转载请注明出处并保持作品的完整性

在前面我介绍过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的更多相关文章

  1. STL标准库-容器-set与multiset

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. set与multiset关联容器 结构如下 set是一种关联容器,key即value,value即key.它是自动排序,排序特点依据key se ...

  2. STL标准库-容器-deque

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. deque双向开口可进可出的容器 我们知道连续内存的容器不能随意扩充,因为这样容易扩充别人那去 deque却可以,它创造了内存 ...

  3. STL标准库-容器-vector

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. 向量容器vector是一个动态数组,内存连续,它是动态分配内存,且每次扩张的原来的二倍. 他的结构如下 一 定义 vector ...

  4. C++STL标准库学习笔记(五)set

    前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来,这一篇后面主要都是我的记录了,为了防止大片蓝色字体出现,后面就不改蓝色 ...

  5. C++STL标准库学习笔记(三)multiset

    C++STL标准库学习笔记(三)multiset STL中的平衡二叉树数据结构 前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标 ...

  6. C++STL标准库学习笔记(二)二分查找

    二.STL中的二分查找算法 1.binary_search 2.lower_bound 3.upper_bound 记得#include<algorithm>! 前言: 在这个笔记中,我把 ...

  7. STL标准库-算法-常用算法

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 介绍11种STL标准库的算法,从这11种算法中总结一下算法的基本使用 1.accumulate() 累加 2.for_each( ...

  8. STL标准库-容器-set与map

    STL标准库-容器-set与multiset C++的set https://www.cnblogs.com/LearningTheLoad/p/7456024.html STL标准库-容器-map和 ...

  9. C++STL标准库学习笔记(一)sort

    前言: 近来在学习STL标准库,做一份笔记并整理好,方便自己梳理知识.以后查找,也方便他人学习,两全其美,快哉快哉! 这里我会以中国大学慕课上北京大学郭炜老师的<程序设计与算法(一)C语言程序设 ...

随机推荐

  1. HDU 3466 Proud Merchants(0-1背包)

    http://acm.hdu.edu.cn/showproblem.php?pid=3466 题意: 最近,iSea去了一个古老的国家.在这么长的时间里,它是世界上最富有和最强大的王国.结果,这个国家 ...

  2. MVC ---- 无法将类型"System.Data.EntityState"隐式转换为"System.Data.Entity.EntityState"

    1.EF 5.0解决方法 先卸载EF:Uninstall-Package EntityFramework -Force 在安装EF5.0:Install-Package EntityFramework ...

  3. MongoVUE的Collections数据不显示的解决方法

    问题描述: 使用 mongoDB数据库, 数据添加成功了,使用命令行能查询出来,但在MongoVUE 中数据却不显示  (我使用的是 mongoDB 3.4 的版本) 原因:引擎问题,只要降到2.X版 ...

  4. hdu 1788 最小公倍数(这题面。。。)

    Chinese remainder theorem again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 ...

  5. Python day11 filter函数筛选数据,reduce函数压缩数据的源码详解

    1.filter滤波器函数定义一个数组,需求:过滤出带ii的字符串 arr=['dsdsdii','qqwe','pppdiimmm','sdsa','sshucsii','iisdsa'] def ...

  6. 【转】QT获取系统时间,以及设置日期格式

    http://blog.csdn.net/zzk197/article/details/7498593 例如我要在一个label上设置当前时间 QDateTime time = QDateTime:: ...

  7. IntelliJ IDE 开发Java GUI 入门

    j主要对java 的GUI相关知识进行简单的介绍和总结,整个博客按照创建一个java GUI的顺序进行介绍,期间穿插讲解用到的java Swing的布局.控件等相关知识.本博客所进行的讲解及工程的创建 ...

  8. WPF使用Webbrowser操作网页的主要代码

    1,引用mshtml.dll using mshtml; 2,获取元素属性值 IHTMLDocument2 doc2=(IHTMLDocument)webbrowser1.Document; IHTM ...

  9. Confluence 6 使用 LDAP 授权连接一个内部目录 - 高级设置

    ted Groups 为嵌套组启用或禁用支持. 一些目录服务器能够允许你在一个组中定义另外一个组.在这种结构下的用户组称为用户组嵌套.嵌套组的配置能够让子用户组继承上级用户组的权限,是系统的权限配置变 ...

  10. 安卓本地化之SharedPreferences

    SharedPreferences的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息,用Sqlite数据库来存放并不划算,因为数据库连接跟操作等耗时大大影响了程序的 ...