字符串哈希算法(以ELFHash详解)

 

更多字符串哈希算法请参考:http://blog.csdn.net/AlburtHoffman/article/details/19641123

先来了解一下何为哈希:

哈希表是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映射到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址。作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。
通过将单向数学函数(有时称为“哈希算法”)应用到任意数量的数据所得到的固定大小的结果。如果输入数据中有变化,则哈希也会发生变化。哈希可用于许多操作,包括身份验证和数字签名。也称为“消息摘要”。
 
简单解释:哈希(Hash)算法,即散列函数。它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。
 
个人心得:哈希就是用进行函数映射,用key对应此时的值,然后对这个值进行查询时直接对key的地址进行查看就好了,思想简单,用起来真的复杂。我们还是简单学一下ELFHash吧
// ELF Hash Function
2 unsigned int ELFHash(char *str)
3 {
4 unsigned int hash = 0;
5 unsigned int x = 0;
6
7 while (*str)
8 {
9 hash = (hash << 4) + (*str++);//hash左移4位,把当前字符ASCII存入hash低四位。
10 if ((x = hash & 0xF0000000L) != 0)
11 {
12 //如果最高的四位不为0,则说明字符多余7个,现在正在存第7个字符,如果不处理,再加下一个字符时,第一个字符会被移出,因此要有如下处理。
13 //该处理,如果最高位为0,就会仅仅影响5-8位,否则会影响5-31位,因为C语言使用的算数移位
14 //因为1-4位刚刚存储了新加入到字符,所以不能>>28
15 hash ^= (x >> 24);
16 //上面这行代码并不会对X有影响,本身X和hash的高4位相同,下面这行代码&~即对28-31(高4位)位清零。
17 hash &= ~x;
18 }
19 }
20 //返回一个符号位为0的数,即丢弃最高位,以免函数外产生影响。(我们可以考虑,如果只有字符,符号位不可能为负)
21 return (hash & 0x7FFFFFFF);
22 }

然后用一个例题实践一下吧吧,hdu1800

#include <bits/stdc++.h>
using namespace std; typedef unsigned int ui;
const int N = 7003, MOD = 7003;
int Hash[N], num[N];
int res;
int ELFhash(char *str)//思想就是一直杂糅,使字符之间互相影响
{
ui h = 0, g;
while(*str)
{
h = (h<<4) + *str++; //h左移4位,当前字符占8位,加到h中进行杂糅
if((g = h & 0xf0000000) != 0) //取h最左四位的值,若均为0,则括号中执行与否没区别,故不执行
{
h ^= g>>24; //用h的最左四位的值对h的右起5~8进行杂糅
h &= ~g;//清空h的最左四位
}
}
return h; //因为每次都清空了最左四位,最后结果最多也就是28位二进制整数,不会超int
}
void hash_table(char *str)
{
int k = ELFhash(str);
int t = k % MOD;
while(Hash[t] != k && Hash[t] != -1) t = (t + 1) % MOD;//开放地址法处理hash
if(Hash[t] == -1) num[t] = 1, Hash[t] = k;
else res = max(res, ++num[t]);
}
int main()
{
int n;
char str[100];
while(~ scanf("%d", &n))
{
getchar();
res = 1;
memset(Hash, -1, sizeof Hash);
for(int i = 1; i <= n; i++)
{
scanf("%s", str);
int j = 0;
while(str[j] == '0') j++;
hash_table(str + j);
}
printf("%d\n", res);
}
return 0;
}

ELFhash的更多相关文章

  1. ELFHash算法解释

    // ELF Hash Function unsigned int ELFHash(char *str) { unsigned int hash = 0; unsigned int x = 0; wh ...

  2. 字符串哈希算法(以ELFHash详解)

    更多字符串哈希算法请参考:http://blog.csdn.net/AlburtHoffman/article/details/19641123 先来了解一下何为哈希: 哈希表是根据设定的哈希函数H( ...

  3. ELFhash - 优秀的字符串哈希算法

    ELFhash - 优秀的字符串哈希算法 2016年10月29日 22:12:37 阅读数:6440更多 个人分类: 算法杂论算法精讲数据结构 所属专栏: 算法与数据结构   版权声明:本文为博主原创 ...

  4. hash算法总结收集

    hash算法的意义在于提供了一种快速存取数据的方法,它用一种算法建立键值与真实值之间的对应关系,(每一个真实值只能有一个键值,但是一个键值可以对应多个真实值),这样可以快速在数组等条件中里面存取数据. ...

  5. 各种字符串Hash函数比较(转)

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

  6. 哈希(Hask)

     编辑 Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射 ...

  7. 常用的Hash算法

    1.RSHash unsigned int RSHash(const std::string& str) {    unsigned int b    = 378551;    unsigne ...

  8. 海量字符串查找——bloom filter,c

    对于海量字符串的查找,一般有两种方法,一种是建树,还有一种就是bf算法,即布隆过滤器,这个从原来上讲比较简单,也易于实现,主要就是根据哈希算法来实现. int len(char *ch) { int ...

  9. 一些常用的字符串hash函数

    unsigned int RSHash(const std::string& str) { unsigned int b = 378551; unsigned int a = 63689; u ...

随机推荐

  1. laravel上传文件FTP驱动配置

    FTP驱动配置 Laravel 的文件系统集成了 FTP 操作,不过,框架默认的配置文件 filesystems.php 并没有提供示例配置.如果你需要配置一个FTP文件系统,可以使用以下示例配置: ...

  2. js 敏感词过滤

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  3. Python格式化字符 %s %d %f

    格式 描述%% 百分号标记 #就是输出一个%%c 字符及其ASCII码%s 字符串%d 有符号整数(十进制)%u 无符号整数(十进制)%o 无符号整数(八进制)%x 无符号整数(十六进制)%X 无符号 ...

  4. python 笔记数据类型

    python基础: 采用缩进方式     4个空格的缩进 大小写敏感 数据类型和变量 数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值,但是,计算机能处理的 ...

  5. :代理模式:proxy

    #ifndef __PROXY_H__ #define __PROXY_H__ class Subject { public: Subject(){} virtual ~Subject(){} vir ...

  6. Cracking The Coding Interview 2.5

    这题的思想来自于http://hawstein.com/posts/2.5.html,重新实现了一下 用hash来记录循环的起点 //Given a circular linked list, imp ...

  7. windows消息传送(自定义消息和WM_COPYDATA)

    通过SendMessge实现的进程间通信. 0x01 自定义消息 1,WINDOWS中自定义消息的定义和使用: (1)在WNDOWS中消息分系统消息和自定义消息.系统消息定义从0到0x3FF,使用0x ...

  8. 关于iOS开发常用的一些东西

    备注:这里只是个人的观点,有的地方也是copy,多多指教,个人笔记,有侵犯你们版权的地方还望海涵!!! 1. 自定义键盘:inputView重写,可以用重写UITextField来实现 2. UIDa ...

  9. DevExpress v18.1新版亮点——Report & Dashboard Server

    用户界面套包DevExpress v18.1日前正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress Report Server v18.1 的新功能,快来下载试用新 ...

  10. merge into用法小结

    CREATE OR REPLACE PROCEDURE PRO_ZXC(O_NO OUT NUMBER,O_NOTE OUT NUMBER)ASBEGIN O_NO:=1; MERGE INTO QQ ...