BKDRhash
哈希:
字符串(数字同理):
例如有100000个字符串,现在要插入一些字符串,插入前比较是否已经存在避免含有重复数据
用暴力计较的话会比较慢,在某字符串插入时,最好的情况是在第一个位置就遇见该字符串,但如果在比较了100000后发现没有某字符串,然后进行插入,那么比较100000次的比较则是浪费时间
用映射的方法可以很快判断是否存在某字符串:
1、把100000个字符串存放在经哈希函数返回的哈希地址内
2、将待插入的字符串也经哈希函数,查看返回的哈希地址里是否已经有了某字符串或是否和含有的字符串相等(发生冲突时),没有就插入
每个串都有自己的哈希地址。这取决于需要一个好的哈希函数(BKDRhash),尽量让每个字符串的哈希地址不发生冲突。但有时总存在两个串的哈希地址相同,发生冲突,别急,有解决冲突的办法。
选用的哈希函数:
哈希函数的目的就是为了产生字符串的哈希值,让不同的字符串尽量产生不同的哈希值的函数就是好的哈希函数,全然不会产生同样的哈希函数就是完美的。
处理冲突的方法:
处理冲突的方法有多种,开放定址、拉链法、公共溢出区等。
装载因子,即哈希表的饱和程度:
一般来说装载因子越小越好。装载因子越小,碰撞也就越小。哈希表的速度就会越快,但是这样会大大的浪费空间。假如装载因子为0.1。那么哈希表仅仅有10%的空间被真正利用。其余的90%都浪费了,这就是时间和空间的矛盾点。为了平衡,如今大部分採用的是0.75作为装载因子,装载因子达到0.75,那么就动态添加哈希表的大小。
因此,在编写代码之前,首先需要根据所要处理的数据,选择合适的hash函数和冲突处理办法。开放定址需要空闲存储单元,所需要的表比实际容量大,而且容易产生二次聚集发生新冲突。链地址使用链表存储关键字,可以随时插入新数据,数据量大小不受限制。缺点是要用到指针,给新单元分配地址需要时间,会一定程度上减慢算法速度,但影响不大可以忽略。
BKDRhash函数代码如下:
unsigned int BKDRHash(char *str)
{
unsigned int seed = ;//也可以乘以31、131、1313、13131、131313..
unsigned int hash = ;
while(*str)
{
hash = hash*seed + (*str++);
}
return hash%0x7FFFFFFF;//MAX代表hash表长度
}
测试代码:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string.h>
#define MAX 40000
using namespace std;
struct node
{
char name[];
}que[MAX];
/*
BKDRHash函数的解析链接:
http://blog.csdn.net/djinglan/article/details/8812934
*/
unsigned int BKDRHash(char *str)
{
unsigned int seed = ;//也可以乘以31、131、1313、13131、131313..
unsigned int hash = ;
while(*str)
{
hash = hash*seed + (*str++);
} return hash%;//最好对一个大的素数取余
}
int main()
{
int i=,n,t,j;
char a[MAX][];
char temp[];
memset(a,,sizeof(a)); cin >> n;
for(i=;i<n;i++)
{
cin >> que[i].name;
strcpy(a[BKDRHash(que[i].name)],que[i].name);
}
cout << "请输入要查找的字符串:";
while(~scanf("%s",temp))
{
if(strcmp(a[BKDRHash(temp)],temp)==)
cout << "yes" << endl;
else
{
cout << "no" << endl;
strcpy(a[BKDRHash(temp)],temp);
strcpy(que[i++].name,temp);
}
}
for(j=;j<=i;j++)
{
cout << que[j].name << endl;//含有的所有字符串
}
return ;
}
转载用拉链法解决冲突的方法:http://www.cnblogs.com/liuliuliu/p/3966851.html (小弟认为此定为大神级人物,膜拜O(∩_∩)O哈哈~)
BKDRhash的更多相关文章
- BKDRhash实现
参考了一些有关于哈希算法的博客,里面都有提到BKDR哈希算法,在博客:各种字符串Hash函数中有对各种hash算法进行测试,测试关于哈希冲突,以及散列的质量,得到的结果可以参考以上博文. BKDRha ...
- 哈希表之bkdrhash算法解析及扩展
BKDRHASH是一种字符哈希算法,像BKDRHash,APHash.DJBHash,JSHash,RSHash.SDBMHash.PJWHash.ELFHash等等,这些都是比較经典的,通过http ...
- HDU 4821 String(BKDRHash)
http://acm.hdu.edu.cn/showproblem.php?pid=4821 题意:给出一个字符串,现在问你可以找出多少个长度为M*L的子串,该子串被分成L个段,并且每个段的字符串都是 ...
- 逐步实现hash算法(基于BKDRhash函数)
哈希(Hash)算法,即散列函数.它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程.同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出.hash算法 ...
- BKDRHash函数
unsigned int BKDRHash(char*str) { unsigned ;// 31 131 1313 13131 131313 etc.. unsigned ; while(*str) ...
- 【字符串哈希】【BKDRhash】【Rabin-Karp算法】模板
#include<cstdio> #include<iostream> #include<cstring> #include<string> #incl ...
- Hihocoder #1602 : 本质不同的回文子串的数量 manacher + BKDRhash
#1602 : 本质不同的回文子串的数量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个字符串S,请统计S的所有子串中,有多少个本质不同的回文字符串? 注意如果 ...
- HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)
Reincarnation Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) P ...
- BKDRHash 算法 php 版本( 可用于 字符串 hash 为int 转)
<?php function BKDRHash($str) { $seed = 131; // 31 131 1313 13131 131313 etc.. $hash = 0; $cnt = ...
- BKDRHash算法的初步了解
字符串hash最高效的算法, 搜了一下, 原理是: 字符串的字符集只有128个字符,所以把一个字符串当成128或更高进制的数字来看,当然是唯一的 这里unsigned不需要考虑溢出的问题, 不过 ...
随机推荐
- Thinkphp 架构笔记
多个模块的时候,公共模块Common必须和其他模块放在同一个目录下,否则拓展配置“LOAD_EXT_CONFIG”会无效
- PHP实现微信申请退款流程实例源码
https://www.jb51.net/article/136476.htm 目录 前期准备: 前面讲了怎么实现微信支付,详见博文:PHP实现微信支付(jsapi支付)流程 和ThinkPHP中实 ...
- 关于python的元组操作
关于元组: 元组和列表是类似的,但是元组中的数据是不可以修改的. 元组是一对 () 元组操作: 元组是不可以修改的所以对元组的操作极少 定义空元组(因为元组一旦创建,数据不可被修改,所以极少创建空元组 ...
- 策略模式(Strategy)(策略类,场景不同策略不同,环境策略分离组合,)
(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换.) 例:button 与 listener ,在使用时具体根据情况实例化listener,做不同的操作. 背景 在软件开发中常常遇到这 ...
- 提升mysql服务器性能(索引与查询优化)
原文:提升mysql服务器性能(索引与查询优化) 版权声明:皆为本人原创,复制必究 https://blog.csdn.net/m493096871/article/details/90138407 ...
- Uva437 The Tower of Babylon
https://odzkskevi.qnssl.com/5e1fdf8cae5d11a8f572bae96d6095c0?v=1507521965 Perhaps you have heard of ...
- 洛谷P1514 [NOIP2010提高组T4]引水入城
P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城 ...
- php分页查询的简单实现代码
<body><h1>分页查询</h1><?phpinclude("DADB.class.php");$db=new DADB();$tj= ...
- JSON和JSONP,原来ajax引用这个来实现跨域访问的
由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯 ...
- 引用CDN内容的方法总结
1.1.1 摘要 CDN相信大家都听说过,甚至使用过相关的技术,也许有些人会回答“没有听说过和使用过该技术”,真的是这样吗? CDN的全称是Content Delivery Network,即内容分发 ...