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

在前面我介绍过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. FAST:通过Floodlight控制器下发流表

    参考: Floodlight+Mininet搭建OpenFlow(四):流表操作 通过Floodlight控制器下发流表 下发流表的方式有两种: 1.借助Floodlight的北向API,利用curl ...

  2. 【TCP/IP详解 卷一:协议】第十二章 广播和多播

    建议参考:广播和多播 IGMP 12.1 引言 IP地址知识点回顾: IP地址分为三种:(1)单播地址 (2)广播地址 (3)多播地址 另外一种是,IP地址一般划分成五类:A-E类. 单播 考虑 类似 ...

  3. BZOJ 1003: [ZJOI2006]物流运输(spfa+dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1003 题意: 思路: 首先用spfa计算一下任意两天之内的最短路,dis[a][b]表示的就是在第a ...

  4. UVa 11300 分金币

    https://vjudge.net/problem/UVA-11300 题意: 圆桌上有n个人,每个人都有一定的初始金币,每个人可以给他旁边的人一些金币,最终使每个人的金币数相等.计算最少需要转手的 ...

  5. UVa 11584 划分成回文串

    https://vjudge.net/problem/UVA-11584 题意: 给出一串字符,把它划分成尽量少的回文串. 思路: 用d[i]表示划分到i时所能划分的最小个数,转移方程为d[i]=mi ...

  6. JMeter源码导入到Intellij IDEA

    环境: Windows10,jdk1.8,Intellij IDEA 2018.1.5 x64,apache-jmeter-4.0_src.zip  http://jmeter.apache.org/ ...

  7. 用java代码将数组元素顺序颠倒

    package test; public class Recover { public int[] reverse(int[] a) { int[] b = new int[a.length]; in ...

  8. android中 检查网络连接状态的变化,无网络时跳转到设置界面

    1:在AndroidManifest.xml中加一个声明 <receiver android:name="NetCheckReceiver">    <inten ...

  9. Codeforces 757B - Bash's Big Day(分解因子+hashing)

    757B - Bash's Big Day 思路:筛法.将所有因子个数求出,答案就是最大的因子个数,注意全为1的特殊情况. 代码: #include<bits/stdc++.h> usin ...

  10. 个人学期总结及Python+Flask+MysqL的web建设技术过程

    一个学期即将过去,我们也迎来了2018年.这个学期,首次接触了web网站开发建设,不仅是这门课程,还有另外一门用idea的gradle框架来制作网页. 很显然,用python语言的flask框架更加简 ...