哈希:

字符串(数字同理):

例如有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的更多相关文章

  1. BKDRhash实现

    参考了一些有关于哈希算法的博客,里面都有提到BKDR哈希算法,在博客:各种字符串Hash函数中有对各种hash算法进行测试,测试关于哈希冲突,以及散列的质量,得到的结果可以参考以上博文. BKDRha ...

  2. 哈希表之bkdrhash算法解析及扩展

    BKDRHASH是一种字符哈希算法,像BKDRHash,APHash.DJBHash,JSHash,RSHash.SDBMHash.PJWHash.ELFHash等等,这些都是比較经典的,通过http ...

  3. HDU 4821 String(BKDRHash)

    http://acm.hdu.edu.cn/showproblem.php?pid=4821 题意:给出一个字符串,现在问你可以找出多少个长度为M*L的子串,该子串被分成L个段,并且每个段的字符串都是 ...

  4. 逐步实现hash算法(基于BKDRhash函数)

    哈希(Hash)算法,即散列函数.它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程.同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出.hash算法 ...

  5. BKDRHash函数

    unsigned int BKDRHash(char*str) { unsigned ;// 31 131 1313 13131 131313 etc.. unsigned ; while(*str) ...

  6. 【字符串哈希】【BKDRhash】【Rabin-Karp算法】模板

    #include<cstdio> #include<iostream> #include<cstring> #include<string> #incl ...

  7. Hihocoder #1602 : 本质不同的回文子串的数量 manacher + BKDRhash

    #1602 : 本质不同的回文子串的数量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个字符串S,请统计S的所有子串中,有多少个本质不同的回文字符串? 注意如果 ...

  8. HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) P ...

  9. BKDRHash 算法 php 版本( 可用于 字符串 hash 为int 转)

    <?php function BKDRHash($str) { $seed = 131; // 31 131 1313 13131 131313 etc.. $hash = 0; $cnt = ...

  10. BKDRHash算法的初步了解

    字符串hash最高效的算法,  搜了一下,  原理是: 字符串的字符集只有128个字符,所以把一个字符串当成128或更高进制的数字来看,当然是唯一的 这里unsigned不需要考虑溢出的问题,  不过 ...

随机推荐

  1. excel2013做数据透视表

    excel2013做数据透视表     Excel最新版更新到2013,相比2003.2007和2010,2013的excel界面方面有一定变化,在操作方面也有一定的便捷性.那么如何使用excel20 ...

  2. 常用命令4-文件搜索命令 2- which

    大家发现,cd 使用whereis和使用which都找不到他所在位置.是因为cd是linux的shell内置命令.那什么是shell,就是当前咱们操作界面.咱们看到的ls等命令都是通过外部安装的,所以 ...

  3. Lab2 内存管理(实现细节)

    lab2 中的变动 bootloader 的入口发生了改变 bootloader不像lab1那样,直接调用kern_init函数,而是先调用位于lab2/kern/init/entry.S中的kern ...

  4. LINNX查看当前登录的用户

    W w命令主要是查看当前登录的用户,这个命令相对来说比较简单.我们来看一下截图. 在上面这个截图里面呢,第一列user,代表登录的用户,第二列,tty代表用户登录的终端号,因为在linux中并不是只有 ...

  5. 【CS Round #44 (Div. 2 only) A】Frequent Numbers

    [链接]h在这里写链接 [题意] 在这里写题意 [题解] 大水题 [错的次数] 0 [反思] 在这了写反思 [代码] /* */ #include <cstdio> #include &l ...

  6. 【笔记】LR录制方式和常用函数

    本文为本人复习LR时,笔记整理.以备后续查阅. 注意:录制脚本时,选择不同的协议下录制时设置选项也是不相同的,我们这里介绍的是基于协议web(http/html)录制选项设置. 对于web(http/ ...

  7. linux安装软件报错: Can't locate ExtUtils/Embed.pm in @INC...

    安装snmp服务, 中间报错: Can't locate ExtUtils/Embed.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/l ...

  8. spring拦截器Interceptor

    在Spring Boot中,拦截器可以分为两种类型: 一是WebMVC,负责拦截请求,类似于过滤器,对用户的请求在Controller接收前进行处理,在Controller处理完成后加工结果等.使用时 ...

  9. Leetcode832.Flipping an Image翻转图像

    给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果. 水平翻转图片就是将图片的每一行都进行翻转,即逆序.例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]. 反转图片的 ...

  10. Mysql+php报错原因

    SQL syntax --语法错误,看near,错误会在near后引号中的内容 的附近 Table/Database....... dosen't existes ---表/库(库名/表名) 不存在 ...