关于字符串hash,就一句话:

           把字符串有效地转化为一个整数

在计算机里,用的是二进制编码。在很多语言里,都是用数字作为数组的下标。因为用数字来存储、表达一个object非常方便。

 

如果能有一种算法,把每个字符串有效地、唯一的映射到每个不同的整数,我们就能很好的处理字符串。

 

 

hash的思想是挺好理解的,那么hash的算法应该怎么去写?

 

不建议写自然溢出的hash算法,因为新的字符串的题目出题人都喜欢卡这个

 

单hash:

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <string.h>
 5 #include <stdlib.h>
 6 #include <math.h>
 7 #include <queue>
 8 #include <set>
 9 
10 #define INF 0x3f3f3f3f
11 #define pii pair<int,int>
12 #define LL long long
13 using namespace std;
14 typedef unsigned long long ull;
15 const int maxn = 2e6+6;
16 
17 
18 int a[maxn];
19 char s[maxn];
20 
21 
22 ull base = 131;
23 ull mod = 1e9+7;
24 ull p[maxn],h[maxn];
25 void Hash(char s[]){
26     int n = strlen(s);
27     p[0] = 1;
28     for (int i=1;i<=n;i++){
29         p[i] = p[i-1] * base % mod;
30     }
31     for (int i=1;i<=n;i++){
32         h[i] = (h[i-1]*base %mod + s[i])%mod;
33     }
34 }
35 ull get(int l,int r){
36     return (h[r] - h[l-1]*p[r-l+1] % mod + mod)%mod;
37 }
38 
39 int main(){
40     int n;
41     int ans = 1;
42     scanf("%d",&n);
43     for (int i=1;i<=n;i++){
44         scanf("%s",s+1);
45         int len = strlen(s+1);
46         //cout << len << endl;
47         Hash(s+1);
48         a[i] = h[len];
49     }
50     sort(a+1,a+1+n);
51     for (int i=2;i<=n;i++){
52         if (a[i]!=a[i-1])
53             ans++;
54     }
55     printf("%d\n",ans);
56     return 0;
57 }

 

双hash:

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <string.h>
 5 #include <stdlib.h>
 6 #include <math.h>
 7 #include <queue>
 8 #include <set>
 9 
10 #define INF 0x3f3f3f3f
11 #define pii pair<int,int>
12 #define LL long long
13 using namespace std;
14 typedef unsigned long long ull;
15 const int maxn = 2e6+6;
16 
17 struct Node{
18     int x,y;
19 }a[maxn];
20 
21 char s[maxn];
22 
23 
24 ull base = 131;
25 ull mod1 = 1e9+7;
26 ull mod2 = 1e9+9;
27 ull p[maxn],h[maxn];
28 bool cmp(Node a,Node b){
29     return a.x<b.x;
30 }
31 void Hash1(char s[]){
32     int n = strlen(s);
33     p[0] = 1;
34     for (int i=1;i<=n;i++){
35         p[i] = p[i-1] * base % mod1;
36     }
37     for (int i=1;i<=n;i++){
38         h[i] = (h[i-1]*base % mod1 + s[i]) % mod1;
39     }
40 }
41 
42 void Hash2(char s[]){
43     int n = strlen(s);
44     p[0] = 1;
45     for (int i=1;i<=n;i++){
46         p[i] = p[i-1] * base % mod2;
47     }
48     for (int i=1;i<=n;i++){
49         h[i] = (h[i-1]*base % mod2 + s[i]) % mod2;
50     }
51 }
52 
53 int get1(int l,int r){
54     return (h[r] - h[l-1]*p[r-l+1] % mod1 + mod1 ) % mod1;
55 }
56 
57 int get2(int l,int r){
58     return (h[r] - h[l-1]*p[r-l+1] % mod2 + mod2 ) % mod2;
59 }
60 
61 int main(){
62     int n;
63     int ans = 1;
64     scanf("%d",&n);
65     for (int i=1;i<=n;i++){
66         scanf("%s",s+1);
67         int len = strlen(s+1);
68         //cout << len << endl;
69         Hash1(s+1);
70         a[i].x = h[len];
71         Hash2(s+1);
72         a[i].y = h[len];
73     }
74     sort(a+1,a+1+n,cmp);
75     for (int i=2;i<=n;i++){
76         if (a[i].x!=a[i-1].x ||a[i].y!=a[i-1].y)
77             ans++;
78     }
79     printf("%d\n",ans);
80     return 0;
81 }

 

 

 

 

 

 

推荐博客:https://www.cnblogs.com/henry-1202/p/10324966.html