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语言程序设 ...
随机推荐
- shiro(1) 介绍
一.什么是shiro (1)属性:java框架 (2)用途:身份验证.用户授权.加密.会话管理 (3)优点:轻量.易用 二.三大组件 (1)subject:代表当前主体,与当前应用交互的任何东西都是s ...
- UVa 1152 和为0的4个值(二分查找)
https://vjudge.net/problem/UVA-1152 题意:给定4个n元素集合A,B,C,D,要求分别从中选取一个元素a,b,c,d,使得a+b+c+d=0.问有多少种取法. 思路: ...
- JS post 数组道后台
$("#aSave").click(function () { if ($("#TaskName").val() == "") { aler ...
- Linux下wget下载整个FTP目录(含子目录)--转载
wget -nH -m --ftp-user=your_username --ftp-password=your_password ftp://your_ftp_host/* 解释:-nH:不创建以主 ...
- json字符串在javascript和java代码中的表示方式
最近在使用js写json形式的字符串的时候,当我把json形式的字符串放到函数JSON.parse()的时候,总是报错Uncaught SyntaxError: Unexpected token ' ...
- python 获取格式化时间
#!/usr/bin/python # -*- coding: UTF- -*- import time localtime = time.asctime( time.localtime(time.t ...
- python 基数排序
def radix_sort(array): bucket, digit = [[]], 0 while len(bucket[0]) != len(array): bucket = [[], [], ...
- jQuery双击编辑td数据
html <td class="remark" style="width: 200px;"> {$vo.remark} </td> js ...
- LeetCode--191--位1的个数
问题描述: 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量). 示例 : 输入: 11 输出: 3 解释: 整数 11 的二进制表示为 00000 ...
- Sqlite3,维基百科中的练习:
https://en.wikibooks.org/wiki/SQL_Exercises/The_computer_store 两个相连的表格 Manufactures: code, name prod ...