标签:冲突 算数 for unsigned printf 查找 思想 int 详解
更多字符串哈希算法请参考:http://blog.csdn.net/AlburtHoffman/article/details/19641123
先来了解一下何为哈希:
1 // 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; }
标签:冲突 算数 for unsigned printf 查找 思想 int 详解
原文地址:http://www.cnblogs.com/blvt/p/7953641.html