0x14 Hash

Posted kkkstra

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0x14 Hash相关的知识,希望对你有一定的参考价值。

Hash表

【例题】POJ3349 Snowflake Snow Snowflakes

建立一个哈希表,将N片雪花依次插入。

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 const int INF=0x3f3f3f3f;
 8 const int maxn=100000+10;
 9 const int P=99991;
10 int n;
11 
12 int hash(int *a) 
13     int sum=0, mul=1;
14     for (int i=0; i<6; ++i) 
15         sum=(sum+a[i])%P;
16         mul=(long long)mul*a[i]%P;
17     
18     return (sum+mul)%P;
19 
20 
21 int tot=0, snow[maxn][6], next[maxn], head[maxn];
22 bool judge(int *a, int *b) 
23     for (int i=0; i<6; ++i) 
24         for (int j=0; j<6; ++j) 
25             bool flag=1;
26             //顺时针 
27             for (int k=0; k<6; ++k) 
28                 if (a[(i+k)%6] != b[(j+k)%6]) flag=0;
29                 //printf("%d %d %d\n", a[(i+k)%6], b[(j+k)%6], flag);
30             
31             //printf("\n");
32             if (flag) return 1;
33             //逆时针
34             flag=1;
35             for (int k=0; k<6; ++k) 
36                 if (a[(i+k)%6] != b[(j-k+6)%6]) flag=0;
37                 //printf("%d %d %d\n", a[(i+k)%6], b[(j-k+6)%6], flag);
38             
39             //printf("\n");
40             if (flag) return 1; 
41         
42     
43     return 0;
44 
45 
46 bool insert(int *a) 
47     int val=hash(a);
48     for (int i=head[val]; i; i=next[i]) 
49         if (judge(snow[i], a)) return 1;
50     
51     //若没有找到相同的雪花,则进行插入 
52     ++tot;
53     memcpy(snow[tot], a, 6*sizeof(int));
54     next[tot]=head[val];
55     head[val]=tot;
56     return 0;
57 
58 
59 int main() 
60     //freopen("a.out", "w", stdout);
61     scanf("%d", &n);
62     for (int i=1; i<=n; ++i) 
63         int a[10];
64         for (int j=0; j<6; ++j)
65             scanf("%d", &a[j]);
66         if (insert(a)) 
67             printf("Twin snowflakes found.\n");
68             return 0;
69         
70      
71     printf("No two snowflakes are alike.\n");
72     return 0;
73   
View Code

字符串Hash

取一固定值P(一般取131或13331),将字符串看作P进制数,并分配一个大于0的数值,代表每种字符。取一固定值M,求出该P进制数对M的余数,作为该字符的Hash值,通常取M=264,即用unsigned long long类型存储,溢出时自动取模。

【例题】CH1401 兔子与兔子

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 const int INF=0x3f3f3f3f;
 8 const int maxn=1000000+10;
 9 char s[maxn];
10 unsigned long long f[maxn], p[maxn];
11 
12 int main() 
13     //freopen("a.txt", "r", stdin);
14     //freopen("a.out", "w", stdout);
15     scanf("%s", s+1);
16     int T;
17     scanf("%d", &T);
18     int n=strlen(s+1);
19     p[0]=1;
20     for (int i=1; i<=n; ++i) 
21         f[i]=f[i-1]*131+(s[i]-a+1);    //Hash(s[1~i])
22         p[i]=p[i-1]*131;    //131^i
23     
24     while (T--) 
25         int l1, r1, l2, r2;
26         scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
27         unsigned long long hash1=f[r1]-f[l1-1]*p[r1-l1+1];
28         unsigned long long hash2=f[r2]-f[l2-1]*p[r2-l2+1];
29         if (hash1==hash2) puts("Yes");
30         else puts("No");
31     
32     return 0;
33   
View Code

【例题】POJ3974 Palindrome

枚举回文中心,提前预处理出正着和反着的Hash值

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 const int INF=0x3f3f3f3f;
 8 const int maxn=1000000+10;
 9 char s[maxn];
10 unsigned long long f1[maxn], f2[maxn], p[maxn];
11 
12 int main() 
13     //freopen("a.txt", "r", stdin);
14     //freopen("a.out", "w", stdout);
15     int kase=0;
16     p[0]=1;
17     for (int i=1; i<=maxn; ++i)
18         p[i]=p[i-1]*131;    //131^i 
19     while (~scanf("%s", s+1)) 
20         int n=strlen(s+1);
21         if (n==3&&s[1]==E&&s[2]==N&&s[3]==D)
22             break;
23         printf("Case %d: ", ++kase);
24         for (int i=1; i<=n; ++i)    //正着算一遍 
25             f1[i]=f1[i-1]*131+(s[i]-a+1);
26         for (int i=n; i>=1; --i)    //反着算一遍 
27             f2[i]=f2[i+1]*131+(s[i]-a+1);
28         int ans=-INF;
29         for (int i=1; i<=n; ++i)     //枚举回文中心 
30             int l=1, r=min(i-1, n-i);
31             while (l<r)     //奇回文串 
32                 int mid=(l+r+1)>>1;
33                 if (f1[i-1]-f1[i-1-mid]*p[mid]==f2[i+1]-f2[i+1+mid]*p[mid]) l=mid;
34                 else r=mid-1;
35             
36             ans=max(ans, l*2+1);
37             l=1, r=min(i, n-i);
38             while (l<r)     //偶回文串 
39                 int mid=(l+r+1)>>1;
40                 if (f1[i]-f1[i-mid]*p[mid]==f2[i+1]-f2[i+1+mid]*p[mid]) l=mid;
41                 else r=mid-1;
42             
43             ans=max(ans, l*2);
44         
45         printf("%d\n", ans);
46     
47     return 0;
48   
View Code

 

以上是关于0x14 Hash的主要内容,如果未能解决你的问题,请参考以下文章

0x14 Hash

Presenting view controllers on detached view controllers is discouraged <CallViewController: 0x14

Java集合--HashHash冲突

hash 模式与 history 模式小记

GCC栈溢出保护

将 sbyte[] 固定为字符串 C#