zoukankan      html  css  js  c++  java
  • hash是一门优雅的暴力

    关于字符串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
    ",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
    ",ans);
    80     return 0;
    81 }

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

  • 相关阅读:
    洛谷 AT2000 Leftmost Ball
    洛谷 P1326 足球
    洛谷 P4868 Preprefix sum
    洛谷 P2596 [ZJOI2006]书架
    HDU 3415 Max Sum of Max-K-sub-sequence
    洛谷 P3901 数列找不同
    洛谷 P3609 [USACO17JAN]Hoof, Paper, Scissor蹄子剪刀…
    洛谷 P5749 [IOI2019]排列鞋子
    验证码解决表单重复的原理
    session和浏览器之间的技术内幕
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11330971.html
Copyright © 2011-2022 走看看