zoukankan      html  css  js  c++  java
  • 进制哈希

    进制哈希的作用:把字符赋予进制和模数,将每一个字符串映射为一个小于模数数字。

    具体操作:首先设一个进制数base,并设一个模数mod,进制哈希就是把一个串转化为一个值,这个值是base进制的,储存在哈希表中,注意一下在存入的时候取模一下即可。

    哈希冲突:什么是哈希冲突:比如 wsy 的哈希值是2333,然而 mxq 的哈希值也是2333,这样就会产生哈希冲突,从而让哈希算法判断失误。

    解决办法

    1. 用一个大质数当模数
    2. 双模数哈希:(通过设置两个不同的哈希方式,对于一个字符串,当且仅当两个哈希值都相同时才判定相同。)
    3. 自然溢出法

    核心代码

    #define base 233317
    #define inf 212370440130137957(LL)
    ull mod = inf;
    
    ull hasha(char s[]){
        ll ans=0, len=strlen(s);
        for(ll i=0;i<len;i++){
            ans = (ans*base + (ull)s[i])%mod;
            //枚举该字符串的每一位,与base相乘,转化为base进制,加(ull)是为了防止爆栈搞出一个负数,(ull)是无符号的,但其实加了一个ull是可以不用mod的,加个mod更保险
            //然而加了mod会很玄学,莫名比不加mod慢
        }
        return ans;
    }

    模板题目:P3370 【模板】字符串哈希

     

     1.自然溢出法 AC_Code:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 using namespace std;
     8 typedef long long ll;
     9 typedef unsigned long long ull;
    10 const int maxn = 10000+10;
    11 const ull base = 233317;
    12 const ull mod = 1e9+7;
    13 
    14 int n;
    15 char s[maxn];
    16 ull hash_key[maxn];
    17 
    18 ull get_hash(char s[]){
    19     ull ans=0;
    20     int len=strlen(s);
    21     for(int i=0;i<len;i++){
    22         ans = (ans*base + (ull)s[i]);
    23         //这里不使用mod让它自然溢出,定义为ull的数在超过2^32的时候会自然溢出(自然溢出看队友的解释,相当于自动对pow(2,64)-1 取模,无需再手动取模)
    24         //如果把这个换成上面的hash就会400ms+
    25         //所以说自然溢出大法好
    26     }
    27     return ans;
    28 }
    29 
    30 int main()
    31 {
    32     scanf("%d",&n);
    33     for(int i=1;i<=n;i++){
    34         scanf("%s",s);
    35         hash_key[i] = get_hash(s);
    36     }
    37     sort(hash_key+1,hash_key+1+n);
    38     int ans=1;
    39     for(int i=1;i<n;i++){
    40         if( hash_key[i]!=hash_key[i+1] ){
    41             ans ++;
    42         }
    43     }
    44     printf("%d
    ",ans);
    45     return 0;
    46 }

    2.双哈希AC_Code:(其实就是用两个不同的mod来算hash,哈希冲突的概率是降低了很多,不过常数大,容易被卡,这道题要400ms+)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 using namespace std;
     8 typedef long long ll;
     9 typedef unsigned long long ull;
    10 
    11 const int maxn = 10000+10;
    12 const ull base = 233317;
    13 const ull mod1 = 1e9+7;
    14 const ull mod2 = 212370440130137957;
    15 
    16 int n;
    17 char s[maxn];
    18 struct node{
    19     ll x,y;
    20 }hash_key[maxn];
    21 
    22 bool cmp1(node a, node b){
    23     return a.x < b.x;
    24 }
    25 bool cmp2(node a, node b){
    26     return a.y < b.y;
    27 }
    28 
    29 ull hash1(char s[]){
    30     ull ans=0;
    31     int len=strlen(s);
    32     for(int i=0;i<len;i++){
    33         ans = (ans*base + (ull)s[i])%mod1;
    34     }
    35     return ans;
    36 }
    37 
    38 ull hash2(char s[]){
    39     ull ans=0;
    40     int len=strlen(s);
    41     for(int i=0;i<len;i++){
    42         ans = (ans*base + (ull)s[i])%mod2;
    43     }
    44     return ans;
    45 }
    46 
    47 int main()
    48 {
    49     scanf("%d",&n);
    50     for(int i=1;i<=n;i++){
    51         scanf("%s",s);
    52         hash_key[i].x = hash1(s);
    53         hash_key[i].y = hash2(s);
    54     }
    55     sort(hash_key+1,hash_key+1+n,cmp1);
    56     sort(hash_key+1,hash_key+1+n,cmp2);
    57     int ans = 1;
    58     for(ll i=1;i<n;i++){
    59         if( hash_key[i].x!=hash_key[i+1].x || hash_key[i].y!=hash_key[i+1].y){
    60             ans ++;
    61         }
    62     }
    63     printf("%d
    ",ans);
    64     return 0;
    65 }

    参考博客:here

  • 相关阅读:
    [转]ThinkPHP中如何使用原生SQL
    php定时回调接口
    [转]mysql dual虚拟表
    [转]mysql变量使用总结
    [转]使用mysql profiles 来查看sql 语句执行计划
    [转]Mysql中的SQL优化与执行计划
    [转]MySQL单列索引和组合索引的区别介绍
    前端开发框架
    sugar crm
    [转]MCC(移动国家码)和 MNC(移动网络码)
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13974517.html
Copyright © 2011-2022 走看看